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 在将源代码提供给他们的编辑器/编译器时会使用什么编码设置.
考虑以下代码:
#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 在将源代码提供给他们的编辑器/编译器时会使用什么编码设置.