Мне нужно пояснить кодировку файлов с помощью g++ в Linux.
У меня есть простой код:
int main ()
{
FILE * pFile;
char buffer[] = { 'x' , 'y' , 'z' ,'é' };
pFile = fopen ("myfile", "wt, ccs=UTF-8");
//pFile = fopen ("myfile", "wt");
fwrite (buffer , sizeof(char), sizeof(buffer), pFile);
fclose (pFile);
return 0;
}
Даже если в строке fopen добавлена часть "ccs = UTF-8", выходной файл этой программы всегда кодируется в iso-8859-1. Тем не менее, если я создаю файл с использованием vi в Linux, содержащий тезисы charations, результирующий файл кодируется в кодировке UTF-8 (я использую команду "файл myfile" для просмотра режима кодирования файла и "xxd -b myfile", подтвердите это поведение).
Поэтому я хотел бы раскрыть:
1- Почему g++ в Linux не создает файл UTF-8 по умолчанию?
2- Какова цель ccs = UTF-8, если созданный файл не закодирован в UTF-8?
3- Как я могу создать файл UTF-8 на основе этого простого кода?
Благодарю.
Возможно, ваш файл находится в ISO-8859-1, но на самом деле это не так. Он просто сломался.
Файл содержит байты A9
, который младший байт UTF-8 представления é
.
Когда вы написали 'é'
, компилятор должен был предупредить вас:
aaa.c:4:38: warning: multi-character character constant [-Wmultichar]
char buffer[] = { 'x' , 'y' , 'z' ,'é' };
^
char
не является типом для символа, это тип для одного байта. GCC обрабатывает многобайтовые символьные литералы как целые числа большого числа. Здесь вы сразу же отбрасываете его на char
, оставляя младший байт: A9
(BTW, é
в ISO-8859-1 - E9
, а не A9
)
Вы открываете файл с кодировкой, но затем сохраняете в нем байты. Байты соответствуют символам ISO-8859-1 xyz
.
Если вы хотите писать символы, а не байты, используйте wchar_t
вместо char
и fputws
вместо fwrite
#include <stdio.h>
#include <wchar.h>
int main ()
{
FILE * pFile;
// note final zero and L indicating wchar_t literal
wchar_t buffer[] = { 'x' , 'y' , 'z' , L'é' , 0};
// note no space before ccs
pFile = fopen ("myfile", "wt,ccs=UTF-8");
fputws(buffer, pFile);
fclose (pFile);
return 0;
}