wint_t
to wchar_t
与什么相同int
to char
, 所以一个实现,其中sizeof(wchar_t) == sizeof(wint_t)
是完全合法的, 就像实现其中sizeof(int) == sizeof(char)被允许 https://stackoverflow.com/q/3860943/995714。事实上对于char
这种情况更糟,因为你不能返回不同的类型getc
, fgetc
...而对于wint_t
如有必要,您可以简单地将其键入为更宽的类型。您还可以看到该标准甚至明确允许它
脚注 327)wchar_t
and wint_t
可以是相同的整数类型。
http://www.iso-9899.info/n1570.html#7.29.1 http://www.iso-9899.info/n1570.html#7.29.1
该标准还表示“值 WCHAR_MIN 和 WCHAR_MAX 不一定对应于扩展字符集的成员" 这没有什么问题。扩展字符集范围可以小于wchar_t
范围,因为同样的情况发生在char
。例如,如果基本字符集是 ASCII,那么它仅使用可用范围的一半(或者更少,如果CHAR_BIT > 8
). wint_t
is
...默认情况下参数提升不变的整数类型,可以保存与扩展字符集成员相对应的任何值,以及至少一个不与扩展字符集任何成员相对应的值(请参见下面的 WEOF);
http://www.iso-9899.info/n1570.html#6.3.1.3 http://www.iso-9899.info/n1570.html#6.3.1.3
所以推测它的尺寸可能比wchar_t
如果扩展字符集远小于wchar_t
放。自从0xFFFF 保证根本不是 Unicode 字符 https://stackoverflow.com/q/20735405/995714,用它来WEOF
是完全有效的,虽然有点奇怪恕我直言,我不知道为什么 MS 这样做
If sizeof(wchar_t) == sizeof(wint_t)
or sizeof(int) == sizeof(char)
那么还有一些值char
and wchar_t
可以代表但是int
and wint_t
不能以防万一char
/wchar_t
是未签名的。在这种情况下,它们之间的转换是实现定义的。如果您正在处理文本文件,这不会有任何问题,但如果您正在读取二进制文件,这会导致问题。无论如何,在这种情况下,为了可移植性,您需要自己显式测试 EOF 和错误
int c;
while((c = /* fgetwc(in) */ fgetc(in)) != EOF || (!feof(in) && !ferror(in)))
fputc(c, out);
这与TI 建议什么 https://processors.wiki.ti.com/index.php/C89_Support_in_TI_Compilers#Misunderstandings_about_TI_C
在目标上sizeof(char)==sizeof(int)
(C2700、C2800、C5400、C5500),您仍然无法可靠地使用getc()
检查文件结尾,因为 0xffff 会被误认为文件结尾。使用feof()
反而。
CMU https://sei.cmu.edu/'s FIO34-C。区分从文件中读取的字符和EOF or WEOF https://wiki.sei.cmu.edu/confluence/display/c/FIO34-C.+Distinguish+between+characters+read+from+a+file+and+EOF+or+WEOF还说
Because EOF
为负数,它不应该匹配任何无符号字符值。然而,这仅适用于实施 https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-implementation哪里的int
类型比char
。在一个实现中int
and char
具有相同的宽度,字符读取函数可以读取并返回具有相同位模式的有效字符EOF
。例如,如果攻击者将类似于 EOF 的值插入到文件或数据流中以改变程序的行为,则可能会发生这种情况。
C 标准仅要求 int 类型能够表示最大值 +32767,并且 char 类型不大于 int。虽然不常见,但这种情况可能会导致整数常量表达式 EOF 与有效字符无法区分;那是,(int)(unsigned char)65535 == -1
。因此,无法使用feof()
and ferror()
检测文件结尾和文件错误可能会导致在极少数实现中错误地识别 EOF 字符,其中sizeof(int) == sizeof(char)
.
在读取宽字符时,这个问题更为常见。这fgetwc(
), getwc()
, and getwchar()
函数返回类型的值wint_t
。该值可以代表读取的下一个宽字符,也可以代表WEOF
,它表示宽字符流的文件结尾。在大多数实现中,wchar_t
类型具有相同的宽度wint_t
,并且这些函数可以返回与以下内容无法区分的字符WEOF
.
在UTF-16字符集中,0xFFFF保证不是一个字符,这允许WEOF
表示为值-1。同样,当将所有 UTF-32 字符视为有符号 32 位整数时,所有 UTF-32 字符都是正数。所有广泛使用的字符集都设计有至少一个不代表字符的值。因此,需要在不考虑 C 编程语言的情况下设计自定义字符集,以防止宽字符或宽度为 的普通字符出现此问题。int
.
See also
- Mightunsigned char 等于 EOF? https://stackoverflow.com/q/29975874/995714
- Can sizeof(int)曾经在托管实施上成为第一吗? https://stackoverflow.com/q/3860943/995714
- 可以有一个实现sizeof (int) == 1“完全符合”? https://stackoverflow.com/q/30836207/995714
- ctype.h 和 sizeof(int) == sizeof(char) https://groups.google.com/g/comp.std.c/c/qC3Vs0BHwNU/m/YTuoBJBwKU4J?pli=1