基于char*in C的多平台Unicode处理,不使用第三方库?

And*_*dyO 5 c unicode winapi utf-8

以下是我发现的最基本的例子(我知道应该定义例如UNICODE/_UNICODE):

Linux的:

#include <stdio.h>

int main() {
  char* str = "Rölf";
  printf("%s\n", str);
}
Run Code Online (Sandbox Code Playgroud)

视窗:

#include <stdio.h>
#include <locale.h>

int main() {
  setlocale(LC_ALL, "");
  wchar_t* str = L"Rölf";
  wprintf(L"%s\n", str);
}
Run Code Online (Sandbox Code Playgroud)

现在,我已经读过,实现它的一种方法是基本上"只使用UTF-8/char到处并且在进行API调用时担心特定于平台的转换".

这将是伟大的 - 让用户提供char*作为我的库的输入,并"简单地"转换它.所以我尝试了基于这个例子的以下片段(我也在其他地方的变化中看到过).如果这实际上有效,那将是惊人的.但它没有:

  char* str = u8"Rölf";
  int len = mbstowcs(NULL, str, 0) + 1;
  wchar_t wstr[len];
  mbstowcs(wstr, str, len);
  wprintf(L"%s\n", wstr);
Run Code Online (Sandbox Code Playgroud)

我也偶然发现了关于控制台字体的讨论以及不正确渲染的原因,所以为了证明这不是控制台问题 - 以下也不起作用(好吧 - L""字面意思.转换后的u8文字没有):

  MessageBoxW(NULL, wstr, L"Rölf", MB_OK);
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我误解了转换过程吗?有没有办法做这项工作?(不使用例如ICU)

And*_*dyO 2

感谢Barmak Shemirani让我意识到MultiByteToWideChar,我找到了一个甚至符合 C99 的解决方案。(顺便说一句,它适用于 Windows 7)

\n\n

请注意,这setlocale()只是控制台输出正确呈现所必需的。我没有使用它来强调 GUI 相关的 API 调用似乎不需要它。

\n\n
#define UNICODE\n#define _UNICODE\n\n#include <stdio.h>\n#include <windows.h>\n//#include <locale.h>\n\nwchar_t* toWide(char* str) {\n  int wchars_num = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);\n\n  wchar_t* wstr = (wchar_t*)malloc(sizeof(wchar_t) * wchars_num);\n  MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, wchars_num);\n\n  return wstr;\n}\n\nint main() {\n  // For output in console to render correctly - as far as the font allows anyway...\n  //setlocale(LC_ALL, "");\n\n  // PLATFORM-AGNOSTIC DATA STRUCTURE WITH UTF-8 TEXT\n  // (Usually not directly next to the platform-specific API calls...)\n  char* str = "R\xc3\xb6lf";\n\n  // PLATFORM-SPECIFIC TEXT HANDLING\n  wchar_t* wstr = toWide(str);\n  printf("%ls\\n", wstr);\n\n  MessageBox(NULL, wstr, L"R\xc3\xb6lf", MB_OK);\n  free(wstr);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我使用它的方式是声明一个由用户填充的数据结构,其中所有文本都是 char* 并假定为 UTF-8。然后在我的库中,我使用特定于平台的 UI API。而对于Windows来说,进行上述UTF-16转换显然是有必要的。

\n