C++ 在 Linux 上编写 UTF-8
C++ writing UTF-8 on Linux
我在 Windows 上用 Visual Studio 用 C++ 编写了以下代码:
FILE* outFile = fopen(outFileName, "a,ccs=UTF-8");
fwrite(buffer.c_str(), buffer.getLength() * sizeof(wchar_t), 1, outFile);
std::wstring newLine = L"\n";
fwrite(newLine.c_str(), sizeof(wchar_t), 1, outFile);
fclose(outFile);
这会正确地以 UTF-8 格式写出文件。
当我编译 运行 Linux 上的相同代码时,文件已创建,但它的长度为零。如果我按如下方式更改 fopen 命令,则会创建文件且长度非零,但所有非 ASCII 字符都显示为垃圾:
FILE* outFile = fopen(outFileName, "a");
ccs=UTF-8 不能在 Linux gcc 上工作吗?
不,在 Windows 上完成的扩展不适用于 Linux、OS-X、Android、iOS 和其他任何地方。微软只是做了这些扩展来实现你编写与其他平台不兼容的代码。
将宽字符串转换为包含 UTF-8 的字节字符串,然后像往常一样将字节写入文件。
有很多方法可以做到这一点,但大多数标准兼容的方法可能是这样的:
#include <iostream>
#include <string>
#include <codecvt>
#include <locale>
using Converter = std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t>;
int main()
{
std::wstring wide = L"Öö Tiib ";
std::string u8 = Converter{}.to_bytes(wide);
// note: I just put the bytes out to cout, you want to write to file
std::cout << std::endl << u8 << std::endl;
}
Demo is there. 它使用 g++ 8.1.0 但 g++ 4.9.x 也可能没问题。
请注意,很少有人需要在 Linux 上使用宽字符串,那里的大部分代码仅使用 utf8。
我在 Windows 上用 Visual Studio 用 C++ 编写了以下代码:
FILE* outFile = fopen(outFileName, "a,ccs=UTF-8");
fwrite(buffer.c_str(), buffer.getLength() * sizeof(wchar_t), 1, outFile);
std::wstring newLine = L"\n";
fwrite(newLine.c_str(), sizeof(wchar_t), 1, outFile);
fclose(outFile);
这会正确地以 UTF-8 格式写出文件。 当我编译 运行 Linux 上的相同代码时,文件已创建,但它的长度为零。如果我按如下方式更改 fopen 命令,则会创建文件且长度非零,但所有非 ASCII 字符都显示为垃圾:
FILE* outFile = fopen(outFileName, "a");
ccs=UTF-8 不能在 Linux gcc 上工作吗?
不,在 Windows 上完成的扩展不适用于 Linux、OS-X、Android、iOS 和其他任何地方。微软只是做了这些扩展来实现你编写与其他平台不兼容的代码。
将宽字符串转换为包含 UTF-8 的字节字符串,然后像往常一样将字节写入文件。 有很多方法可以做到这一点,但大多数标准兼容的方法可能是这样的:
#include <iostream>
#include <string>
#include <codecvt>
#include <locale>
using Converter = std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t>;
int main()
{
std::wstring wide = L"Öö Tiib ";
std::string u8 = Converter{}.to_bytes(wide);
// note: I just put the bytes out to cout, you want to write to file
std::cout << std::endl << u8 << std::endl;
}
Demo is there. 它使用 g++ 8.1.0 但 g++ 4.9.x 也可能没问题。
请注意,很少有人需要在 Linux 上使用宽字符串,那里的大部分代码仅使用 utf8。