fgets 没有使用设置的语言环境

fgets isn't using the set up locale

考虑以下代码:

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

int main()
{
    char test[100];

    printf("WITHOUT LOCALE: á, é, í, ó, ú, ü, ñ, ¿, ¡\n");

    setlocale(LC_CTYPE, "Spanish");

    printf("WITH LOCALE: á, é, í, ó, ú, ü, ñ, ¿, ¡\n");

    fgets(test, 100, stdin);

    printf("WITH FGETS AND LOCALE: %s\n", test);
    return 0;

}

以及 fgets 的以下输入:

á, é, í, ó, ú, ü, ñ, ¿, ¡

我希望它能够根据预先设置的语言环境支持特殊字符。然而,这是输出:

WITHOUT LOCALE: ß, Ú, Ý, ¾, ·, ³, ±, ┐, í
WITH LOCALE: á, é, í, ó, ú, ü, ñ, ¿, ¡
WITH FGETS AND LOCALE:  , ', ¡, ¢, £, ?, ¤, ¨, ­

知道会发生什么吗?

由于我在朝九晚五的工作中反复遇到这样的问题,所以想出了一个side-by-side table of common 8-bit encodings

使用 table,似乎:

  • 您的编辑器将源代码保存在 CP-1252 中(例如 'ó' -> 0xf3
  • 第一个输出行是解释为 (DOS) CP-850 的字节 (0xf3 -> '¾'),
  • 第二行(setlocale()之后)是CP-1252编码(0xf3 -> 'ó'),
  • 第三行在CP-850中读取输入,显示为CP-1252('ó' -> 0xa2 -> '¢').

(我假设 Windows 平台 -- CP-1252 -- 因为 non-Windows 平台不会拿出 CP-850 除非被迫在枪口下。源编码也可以是 ISO 8859-1 / 西欧,或 ISO 8859-9 / 土耳其语,无法用给定的字符集区分。它不可能是 ISO 8859-15,因为那样会把 'ñ' 变成 '€' ,不是 '¤'。它不能是任何其他 ISO 8859 编码,因为只有 -1、-9 和 -15 将 '¿' 变成 '┐'。)

注意C源代码中non-ASCII-7个字符的解释是implementation-defined,所以你要确保你的编辑器、终端(如果有的话)、编译器都同意关于使用的编码。如果可能的话,将您的环境设置为始终使用 Unicode(UTF-8 是最实用的),以避免出现此类问题。我还建议对源代码中的任何内容 non-ASCII-7 使用八进制转义符,因为您不知道 others 在将源代码提供给他们的编辑器/编译器时会使用什么编码设置.