sea*_*ean 10 c printf ansi non-ascii-characters
我试着printf用一些重音字符,例如á é í ó ú:
printf("my name is Seán\n");
DEVC++ IDE中的文本编辑器显示它们很好 - 即源代码看起来很好.我想我需要一些其他库stdio.h,也许还有一些正常的变体printf.
我正在使用在Windows XP上运行的IDE Bloodshed DEVC.
也许最好的方法是使用 Unicode。
\n\n就是这样...
\n\n首先,手动将控制台字体设置为“Consolas”或“Lucida Console”或您可以选择的任何 True-Type Unicode 字体(“光栅字体”可能不起作用,这些字体不是 Unicode 字体,尽管它们可能包含您\有兴趣)。
\n\n接下来,将控制台代码页设置为 65001 (UTF-8),并使用SetConsoleOutputCP(CP_UTF8).
然后使用 .txt 将文本转换为 UTF-8(如果还不是 UTF-8)WideCharToMultiByte(CP_UTF8, ...)。
最后调用WriteConsoleA()输出UTF-8文本。
这是一个可以为您完成所有这些事情的小函数,它是 的“改进”变体wprintf():
int _wprintf(const wchar_t* format, ...)\n{\n int r;\n static int utf8ModeSet = 0;\n static wchar_t* bufWchar = NULL;\n static size_t bufWcharCount = 256;\n static char* bufMchar = NULL;\n static size_t bufMcharCount = 256;\n va_list vl;\n int mcharCount = 0;\n\n if (utf8ModeSet == 0)\n {\n if (!SetConsoleOutputCP(CP_UTF8))\n {\n DWORD err = GetLastError();\n fprintf(stderr, "SetConsoleOutputCP(CP_UTF8) failed with error 0x%X\\n", err);\n utf8ModeSet = -1;\n }\n else\n {\n utf8ModeSet = 1;\n }\n }\n\n if (utf8ModeSet != 1)\n {\n va_start(vl, format);\n r = vwprintf(format, vl);\n va_end(vl);\n return r;\n }\n\n if (bufWchar == NULL)\n {\n if ((bufWchar = malloc(bufWcharCount * sizeof(wchar_t))) == NULL)\n {\n return -1;\n }\n }\n\n for (;;)\n {\n va_start(vl, format);\n r = vswprintf(bufWchar, bufWcharCount, format, vl);\n va_end(vl);\n\n if (r < 0)\n {\n break;\n }\n\n if (r + 2 <= bufWcharCount)\n {\n break;\n }\n\n free(bufWchar);\n if ((bufWchar = malloc(bufWcharCount * sizeof(wchar_t) * 2)) == NULL)\n {\n return -1;\n }\n bufWcharCount *= 2;\n }\n\n if (r > 0)\n {\n if (bufMchar == NULL)\n {\n if ((bufMchar = malloc(bufMcharCount)) == NULL)\n {\n return -1;\n }\n }\n\n for (;;)\n {\n mcharCount = WideCharToMultiByte(CP_UTF8,\n 0,\n bufWchar,\n -1,\n bufMchar,\n bufMcharCount,\n NULL,\n NULL);\n if (mcharCount > 0)\n {\n break;\n }\n\n if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)\n {\n return -1;\n }\n\n free(bufMchar);\n if ((bufMchar = malloc(bufMcharCount * 2)) == NULL)\n {\n return -1;\n }\n bufMcharCount *= 2;\n }\n }\n\n if (mcharCount > 1)\n {\n DWORD numberOfCharsWritten, consoleMode;\n\n if (GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &consoleMode))\n {\n fflush(stdout);\n if (!WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE),\n bufMchar,\n mcharCount - 1,\n &numberOfCharsWritten,\n NULL))\n {\n return -1;\n }\n }\n else\n {\n if (fputs(bufMchar, stdout) == EOF)\n {\n return -1;\n }\n }\n }\n\n return r;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n下面测试这个功能:
\n\n_wprintf(L"\\xA0\\xA1\\xA2\\xA3\\xA4\\xA5\\xA6\\xA7"\n L"\\xA8\\xA9\\xAA\\xAB\\xAC\\xAD\\xAE\\xAF"\n L"\\xB0\\xB1\\xB2\\xB3\\xB4\\xB5\\xB6\\xB7"\n L"\\xB8\\xB9\\xBA\\xBB\\xBC\\xBD\\xBE\\xBF"\n L"\\n"\n L"\\xC0\\xC1\\xC2\\xC3\\xC4\\xC5\\xC6\\xC7"\n L"\\xC8\\xC9\\xCA\\xCB\\xCC\\xCD\\xCE\\xCF"\n L"\\xD0\\xD1\\xD2\\xD3\\xD4\\xD5\\xD6\\xD7"\n L"\\xD8\\xD9\\xDA\\xDB\\xDC\\xDD\\xDE\\xDF"\n L"\\n"\n L"\\xE0\\xE1\\xE2\\xE3\\xE4\\xE5\\xE6\\xE7"\n L"\\xE8\\xE9\\xEA\\xEB\\xEC\\xED\\xEE\\xEF"\n L"\\xF0\\xF1\\xF2\\xF3\\xF4\\xF5\\xF6\\xF7"\n L"\\xF8\\xF9\\xFA\\xFB\\xFC\\xFD\\xFE\\xFF"\n L"\\n");\n\n_wprintf(L"\\x391\\x392\\x393\\x394\\x395\\x396\\x397"\n L"\\x398\\x399\\x39A\\x39B\\x39C\\x39D\\x39E\\x39F"\n L"\\x3A0\\x3A1\\x3A2\\x3A3\\x3A4\\x3A5\\x3A6\\x3A7"\n L"\\x3A8\\x3A9\\x3AA\\x3AB\\x3AC\\x3AD\\x3AE\\x3AF\\x3B0"\n L"\\n"\n L"\\x3B1\\x3B2\\x3B3\\x3B4\\x3B5\\x3B6\\x3B7"\n L"\\x3B8\\x3B9\\x3BA\\x3BB\\x3BC\\x3BD\\x3BE\\x3BF"\n L"\\x3C0\\x3C1\\x3C2\\x3C3\\x3C4\\x3C5\\x3C6\\x3C7"\n L"\\x3C8\\x3C9\\x3CA\\x3CB\\x3CC\\x3CD\\x3CE"\n L"\\n");\n\n_wprintf(L"\\x410\\x411\\x412\\x413\\x414\\x415\\x401\\x416\\x417"\n L"\\x418\\x419\\x41A\\x41B\\x41C\\x41D\\x41E\\x41F"\n L"\\x420\\x421\\x422\\x423\\x424\\x425\\x426\\x427"\n L"\\x428\\x429\\x42A\\x42B\\x42C\\x42D\\x42E\\x42F"\n L"\\n"\n L"\\x430\\x431\\x432\\x433\\x434\\x435\\x451\\x436\\x437"\n L"\\x438\\x439\\x43A\\x43B\\x43C\\x43D\\x43E\\x43F"\n L"\\x440\\x441\\x442\\x443\\x444\\x445\\x446\\x447"\n L"\\x448\\x449\\x44A\\x44B\\x44C\\x44D\\x44E\\x44F"\n L"\\n");\nRun Code Online (Sandbox Code Playgroud)\n\n并且应该在控制台中产生以下文本:
\n\n\xc2\xa0\xc2\xa1\xc2\xa2\xc2\xa3\xc2\xa4\xc2\xa5\xc2\xa6\xc2\xa7\xc2\xa8\xc2\xa9\xc2\xaa\xc2\xab\xc2\xac\xc2\xad\xc2\xae\xc2\xaf\xc2\xb0\xc2\xb1\xc2\xb2\xc2\xb3\xc2\xb4\xc2\xb5\xc2\xb6\xc2\xb7\xc2\xb8\xc2\xb9\xc2\xba\xc2\xbb\xc2\xbc\xc2\xbd\xc2\xbe\xc2\xbf\n\xc3\x80\xc3\x81\xc3\x82\xc3\x83\xc3\x84\xc3\x85\xc3\x86\xc3\x87\xc3\x88\xc3\x89\xc3\x8a\xc3\x8b\xc3\x8c\xc3\x8d\xc3\x8e\xc3\x8f\xc3\x90\xc3\x91\xc3\x92\xc3\x93\xc3\x94\xc3\x95\xc3\x96\xc3\x97\xc3\x98\xc3\x99\xc3\x9a\xc3\x9b\xc3\x9c\xc3\x9d\xc3\x9e\xc3\x9f\n\xc3\xa0\xc3\xa1\xc3\xa2\xc3\xa3\xc3\xa4\xc3\xa5\xc3\xa6\xc3\xa7\xc3\xa8\xc3\xa9\xc3\xaa\xc3\xab\xc3\xac\xc3\xad\xc3\xae\xc3\xaf\xc3\xb0\xc3\xb1\xc3\xb2\xc3\xb3\xc3\xb4\xc3\xb5\xc3\xb6\xc3\xb7\xc3\xb8\xc3\xb9\xc3\xba\xc3\xbb\xc3\xbc\xc3\xbd\xc3\xbe\xc3\xbf\n\xce\x91\xce\x92\xce\x93\xce\x94\xce\x95\xce\x96\xce\x97\xce\x98\xce\x99\xce\x9a\xce\x9b\xce\x9c\xce\x9d\xce\x9e\xce\x9f\xce\xa0\xce\xa1\xce\xa2\xce\xa3\xce\xa4\xce\xa5\xce\xa6\xce\xa7\xce\xa8\xce\xa9\xce\xaa\xce\xab\xce\xac\xce\xad\xce\xae\xce\xaf\xce\xb0\n\xce\xb1\xce\xb2\xce\xb3\xce\xb4\xce\xb5\xce\xb6\xce\xb7\xce\xb8\xce\xb9\xce\xba\xce\xbb\xce\xbc\xce\xbd\xce\xbe\xce\xbf\xcf\x80\xcf\x81\xcf\x82\xcf\x83\xcf\x84\xcf\x85\xcf\x86\xcf\x87\xcf\x88\xcf\x89\xcf\x8a\xcf\x8b\xcf\x8c\xcf\x8d\xcf\x8e\n\xd0\x90\xd0\x91\xd0\x92\xd0\x93\xd0\x94\xd0\x95\xd0\x81\xd0\x96\xd0\x97\xd0\x98\xd0\x99\xd0\x9a\xd0\x9b\xd0\x9c\xd0\x9d\xd0\x9e\xd0\x9f\xd0\xa0\xd0\xa1\xd0\xa2\xd0\xa3\xd0\xa4\xd0\xa5\xd0\xa6\xd0\xa7\xd0\xa8\xd0\xa9\xd0\xaa\xd0\xab\xd0\xac\xd0\xad\xd0\xae\xd0\xaf\n\xd0\xb0\xd0\xb1\xd0\xb2\xd0\xb3\xd0\xb4\xd0\xb5\xd1\x91\xd0\xb6\xd0\xb7\xd0\xb8\xd0\xb9\xd0\xba\xd0\xbb\xd0\xbc\xd0\xbd\xd0\xbe\xd0\xbf\xd1\x80\xd1\x81\xd1\x82\xd1\x83\xd1\x84\xd1\x85\xd1\x86\xd1\x87\xd1\x88\xd1\x89\xd1\x8a\xd1\x8b\xd1\x8c\xd1\x8d\xd1\x8e\xd1\x8f\nRun Code Online (Sandbox Code Playgroud)\n\n我不知道您的 IDE 在 .c/.cpp 文件中存储非 ASCII 字符的编码,也不知道您的编译器在遇到非 ASCII 字符时会做什么。这部分你应该自己弄清楚。
\n\n只要您提供_wprintf()正确编码的 UTF-16 文本或WriteConsoleA()使用正确编码的 UTF-8 文本进行调用,一切就应该可以正常工作。
Windows 控制台在字符编码方面通常被认为严重损坏。例如,您可以在此处阅读有关此问题的信息。
问题是Windows通常使用ANSI代码页(假设您在西欧或美国Windows-1252),但控制台使用OEM代码页(相同假设下的CP850)。
您有多种选择:
CharToOem())。缺点是,如果用户将输出重定向到文件 ( > file.txt) 并使用记事本等打开该文件,他会看到错误。chcp 1252。wprintf():无论如何,您都需要 TTF 控制台字体。