wchar_t
и функции широких символов (wfopen
и т. Д.) Используются главным образом в Windows для обработки Unicode в кодировке UTF16.
UTF8 использует char
и те же функции C, совместимые с ASCII (* 1006)* и т. д.) Для чтения UTF8 вы можете использовать те же функции Си для ASCII.
Windows не имеет полной поддержки для чтения и отображения UTF8, поэтому вам необходимо выполнить конвертацию между UTF8 и UTF16, чтобы правильно отображать текст.Windows 10 имеет поддержку UTF8 для консольной Windows, см. Соответствующие темы.
#include <stdio.h>
#include <windows.h>
int main(void)
{
const char* filename = "a.csv";
FILE* fp = fopen(filename, "r");
char buf[1000];
fgets(buf, sizeof(buf), fp);
if(strlen(buf) > 2)
if(strncmp(buf, "\xFF\xFE", 2) == 0)
{
printf("UTF16-LE\n");
fclose(fp);
fp = fopen(filename, "rb");
wchar_t wbuf[1000] = { 0 };
fgets((char*)wbuf, sizeof(buf), fp);
MessageBoxW(0, wbuf, L"UTF16-LE", 0);
return 0;
}
if(strlen(buf) > 3)
if(strncmp(buf, "\xEF\xBB\xBF", 3) == 0)
printf("UTF8 with BOM\n");
//assume UTF8 and convert to UTF16:
int size = MultiByteToWideChar(CP_UTF8, 0, buf, -1, NULL, 0);
wchar_t *utf16 = malloc((size + 1) * sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8, 0, buf, -1, utf16, size);
MessageBoxA(0, buf, "ANSI", 0);
MessageBoxW(0, utf16, L"UTF8 converted", 0);
return 0;
}
Если исходный файл имеет формат UTF8, то в основном вы рассматриваете его как ASCII.Просто будьте осторожны с такими функциями, как strtok
, которые не могут обрабатывать вводимые символы вне диапазона ASCII.Единственное другое осложнение - когда вы пытаетесь распечатать его в Windows.Используйте приведенный ниже пример с пользовательской функцией printf
:
void printf_utf8(const char* format, ...)
{
va_list args;
va_start(args, format);
int len = _vscprintf(format, args) + 1;
char *buf = malloc(len);
vsprintf(buf, format, args);
//convert to UTF16 and print
int wbuf_size = MultiByteToWideChar(CP_UTF8, 0, buf, -1, NULL, 0);
wchar_t *wbuf = malloc((wbuf_size + 1) * sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, wbuf_size);
DWORD temp;
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsoleW(h, wbuf, wcslen(wbuf), &temp, 0);
free(wbuf);
free(buf);
}
int main(void)
{
FILE* fp = fopen("a.csv", "r");
if(!fp)
return 0;
char buf[1000];
fgets(buf, sizeof(buf), fp);
printf_utf8("Test %s %d\n", buf, 123);
return 0;
}