c++ - 在unicode c++中编码路径

标签 c++ unicode encoding utf-8

我在打开 UTF-8 路径文件时遇到问题。具有 UTF-8 字符(如西里尔字母或拉丁字母)的路径。我找到了一种使用 _wfopen 解决该问题的方法,但解决该问题的方法是手动使用 UTF (\Uxxxx) 对 UTF-8 字符进行编码。

是否有函数、宏或任何东西,当我提供字符串(路径)时它会返回 Unicode??

是这样的: https://www.branah.com/unicode-converter

我尝试使用 MultiByteToWideChar 但它返回一些不相关的十六进制数字。

尝试过:

std::wstring s2ws(const std::string& s)
{
    int len;
    int slength = (int)s.length() + 1;
    len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
    wchar_t* buf = new wchar_t[len];
    MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
    std::wstring r(buf);
    delete[] buf;
    return r;
}
std::wstring stemp = s2ws(x);
LPCWSTR result = stemp.c_str();

我得到的结果:0055F7E8

提前致谢

更新:

我安装了 boost,现在我想用 boost 来做。有人能帮我提高一下吗。

所以我有一条路: wchar_t path[100] = _T("čaćšžđ\\test.txt");

我需要将其转换为:

wchar_t s[100] = _T("\u010d\u0061\u0107\u0161\u017e\u0111\\test.txt");

最佳答案

这是一种在 Windows 上在 UTF-8 和 UTF-16 之间转换的方法,以及显示输入和输出的存储代码单元的实际值:

#include <codecvt>
#include <iostream>
#include <iomanip>
#include <string>

int main() {
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> convert;

    std::string s = "test";

    std::cout << std::hex << std::setfill('0');
    std::cout << "Input `char` data: ";
    for (char c : s) {
      std::cout << std::setw(2) << static_cast<unsigned>(static_cast<unsigned char>(c)) << ' ';
    }
    std::cout << '\n';

    std::wstring ws = convert.from_bytes(s);

    std::cout << "Output `wchar_t` data: ";
    for (wchar_t wc : ws) {
      std::cout << std::setw(4) << static_cast<unsigned>(wc) << ' ';
    }
    std::cout << '\n';
}

了解输入和输出的实际值很重要,否则您可能无法正确理解您真正需要的转换。例如,在我看来,对于 VC++ 如何处理编码,以及 \Uxxxxxxxx\uxxxx 在 C++ 源代码中的实际作用(例如,它们不一定会生成 UTF-8 数据)。

尝试使用上面显示的代码来查看输入数据的真实情况。


强调我上面写的内容;有强烈的迹象表明您可能没有正确理解对您的输入进行的处理,您需要彻底检查它。

上述程序确实正确地将 ć (U+0107) 的 UTF-8 表示形式转换为单个 16 位代码单元 0x0107,如果您将测试字符串替换为以下内容:

std::string s = "\xC4\x87"; // UTF-8 representation of U+0107

然后,在使用 Visual Studio 的 Windows 上,该程序的输出是:

Input char data: c4 87
Output wchar_t data: 0107

这与您使用测试字符串形成对比,例如:

std::string s = "ć";

或者

std::string s = "\u0107";

这可能会导致以下输出:

Input char data: 3f
Output wchar_t data: 003f

这里的问题是 Visual Studio 不会毫无技巧地使用 UTF-8 作为字符串的编码,因此您从 UTF-8 转换的请求可能不是您真正需要的;或者您确实需要从 UTF-8 进行转换,但您正在使用与实际输入不同的输入来测试潜在的转换例程。


So I have a path: wchar_t path[100] = _T("čaćšžđ\test.txt");

I need it converted to:

wchar_t s[100] = _T("\u010d\u0061\u0107\u0161\u017e\u0111\test.txt");

好的,如果我理解正确的话,你的实际问题是以下失败:

wchar_t path[100] = _T("čaćšžđ\\test.txt");
FILE *f = _wfopen(path, L"w");

但是如果你改为这样写字符串:

wchar_t path[100] = _T("\u010d\u0061\u0107\u0161\u017e\u0111\\test.txt");

然后 _wfopen 调用成功并打开您想要的文件。

首先,这与 UTF-8 完全无关。我假设您找到了一些使用 char 字符串并将其转换为 wchar_t 的解决方法,并且您以某种方式将其解释为涉及 UTF-8 或其他内容。

你用什么编码保存源代码?字符串 L"čaćšžđ\\test.txt" 实际上是否正确保存?尝试关闭源文件并重新打开它。如果某些字符显示为 ?,则部分问题出在源文件编码上。 Windows 在北美和西欧的大部分地区使用的默认编码尤其如此:“西欧 (Windows) - 代码页 1252”。

您还可以检查以下程序的输出:

#include <iomanip>
#include <iostream>

int main() {
    wchar_t path[16] = L"čaćšžđ\\test.txt";

    std::cout << std::hex << std::setfill('0');
    for (wchar_t wc : path) {
        std::cout << std::setw(4) << static_cast<unsigned>(wc) << ' ';
    }
    std::cout << '\n';
    wchar_t s[16] = L"\u010d\u0061\u0107\u0161\u017e\u0111\\test.txt";

    for (wchar_t wc : s) {
        std::cout << std::setw(4) << static_cast<unsigned>(wc) << ' ';
    }
    std::cout << '\n';
}

您需要了解的另一件事是,书写字符的 \uxxxx 形式(称为通用字符名称或 UCN)不是一种可以在 C++ 中与字符串相互转换的形式。当您编译程序并运行时,即当您编写的任何代码可能会尝试生成包含 \uxxxx 的字符串时,UCN 被编译器解释为不同字符的时间早就过去了。唯一可行的 UCN 是直接写入源文件的 UCN。


此外,您错误地使用了 _T()。 IMO 你根本不应该使用 TCHAR 和相关的宏,但如果你确实使用它,那么你应该始终如一地使用它:不要将 TCHAR API 与显式使用 *W API 或 wchar_tTCHAR 的全部意义在于允许代码独立并在那些 wchar_t 和 Microsoft 的“ANSI”API 之间切换,因此使用 TCHAR 然后对 TCHARwchar_t 的假设进行硬编码会破坏整个目的。

你应该只写:

wchar_t path[100] = L"čaćšžđ\\test.txt";

关于c++ - 在unicode c++中编码路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35329149/

相关文章:

mysql - 内存优化的 powershell Out-File - 为大文件编码没有 BOM 的 utf8

c++ - 调试/发布中的控制台程序

c# - 在镜像模式 Windows 7 中以编程方式更改屏幕方向

Python 3 UnicodeDecodeError : 'charmap' codec can't decode byte 0x9d

javascript - 在 Django 中发送字符串元素列表

c# - HttpRequestHeader 内容编码问题

c# - 全局与成员函数

c++ - C++ 中的 Timsort 实现不适用于 10,000 个数字

任何符号的Java正则表达式?

c - 有符号整数和无符号整数是一一对应的吗?