0

我需要通过标准输入输入特殊字符,这样做似乎有问题。我猜 fgetws() 不支持 cp852 (我的操作系统的标准控制台代码页,Win 7 x64 btw)。我应该使用 cp1250 还是其他东西?我尝试在 cmd.exe 中使用 chcp 1250 但这只会持续到我关闭命令提示符。我在 Visual C.

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

int main()
{
    wchar_t query[64];
    setlocale(LC_ALL, "croatian");
    wprintf(L"Insert special characters: ");
    fgetws(query, 64, stdin);
    fputws(query, stdout);
    putchar('\n');
    return 0;
} 

控制台输出示例

4

2 回答 2

2

试图在你的程序中修复错误的语言环境设置是错误的。您应该在您的环境中设置正确的语言环境并在您的代码中使用此值,例如:

setlocale(LC_ALL, "");

这是手册页所说的:

在主程序启动时,默认选择可移植的“C”语言环境。可以通过调用使程序可移植到所有语言环境:

setlocale(LC_ALL, "");

编辑:

看看你给我的最后一张截图,在阅读输入时似乎有些东西混淆了。

案例1:(没有任何调用的那个setlocale

……似乎不太有趣。与(默认)“C”语言环境一样,即使它似乎产生了正确的结果,它也只包含字符 U+00-U+7E,这或多或少是垃圾输入 - 垃圾输出的情况。值 0x9F 是编码 Unicode 字符 'LATIN SMALL LETTER C WITH CARON' (U+010D) 的代码页 825(参见:http : //de.wikipedia.org/wiki/Codepage_852)č

来回传递原始值,如果再次将相同的字节写入终端,则生成相同的输出也就不足为奇了。

案例2:

...看起来更有趣一点。值 0x17a 是 Unicode 字符 'LATIN SMALL LETTER Z WITH ACUTE' (U+017A) 的 UTF-16 编码,与ź屏幕截图中显示的输出完全匹配。由于 fputsw 似乎正确地将其映射到终端编码,因此问题似乎是输入未正确读取。

只是为了确保在进行更改后没有任何混淆 - 您正在运行这样的代码?

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

int main () {
    wchar_t query[64];
    setlocale (LC_ALL, "");

    if (fgetws(query, 64, stdin) == NULL)
      return -1;
    fputws(query, stdout);
    putchar('\n');

    return 0;
}

编辑:

区域设置检查

我忘了提到你的测试中最有趣的事情之一:unicode 字符 'LATIN SMALL LETTER Z WITH ACUTE' (U+017A) ź(第二个屏幕截图中的一个输出)完全表示为值0x9f(那是你在代码页 1250 中使用“原始”字符代码时得到报告。

不知何故,fgetws 似乎使用代码页 1250 而不是代码页 825 来解释字符代码。

对我来说,问题似乎仍然是语言环境设置以某种方式混淆了。可能您应该尝试运行以下代码并查看报告的语言环境。

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

int main (int argc, char *argv[]) {
  char *locale;

  setlocale (LC_ALL, "");
  if ((locale = setlocale (LC_ALL, NULL)) == NULL)
    return -1;

  printf ("%s\n", locale);

  return 0;
}

例如,在我的系统上,这会给出输出:es_ES.utf8有趣的部分是点“。”之后的部分。因为这指定了字符编码(在上面给出的示例中为 utf8)。

要检查的另一件事可能是您正在使用的 Visual Studio 的程序版本,因为在旧版本中设置默认区域设置似乎存在错误。(参见:http ://connect.microsoft.com/VisualStudio/feedback/details/709505/setlocale-lc-all-returns-incorrect-default-system-locale )

于 2013-03-08T21:00:28.953 回答
0

谢谢你 mikyra,试图提供帮助。通过显式地给 setlocale 我的控制台的默认代码页作为第二个参数来解决。像这样:

setlocale( LC_ALL, ".852" );

希望不会出现新的问题。谢谢你,MSDN

于 2013-03-09T01:04:06.990 回答