isspace()
或等于EOF
,则 representable as unsigned char
有效。
getchar()
从stdin中读取下一个字符。
getchar()!=EOF
时;所有getchar()
返回的值都可以表示为unsigned char
?
uintmax_t count_space = 0;
for (int c; (c = getchar()) != EOF; )
if (isspace(c))
++count_space;
这段代码可能导致未定义的行为吗?
答案 0 :(得分:10)
根据C11 WG14 draft version N1570:
§7.21.7.6/ 2
getchar
函数等效于getc
,其参数为stdin。§7.21.7.5/ 2
getc
函数相当于fgetc
...§7.21.7.1/ 2 [
!=EOF
案例] ...fgetc
函数将该字符转换为unsigned char
转换为{{1} [...]中的文本是我的。
即,
int
接受isspace()
值getchar()
值均可表示为getchar()!=EOF
如果你认为它太明显了(“它还能做什么”),那就再想一想。例如,在the related case中:unsigned char
可能未定义,即将字符传递给字符分类函数可能是未定义的行为!
如果isspace(CHAR_MIN)
结果可能是实现定义的:
§6.3.1.3/ 3 否则,新类型已签名且值无法在其中表示;结果是实现定义的,或者引发实现定义的信号。
答案 1 :(得分:1)
getchar()
的返回值与fgetc()
的格式相同。 C11定义了7.21.7.1p2-3中fgetc()
的返回值:
- 如果未设置stream指向的输入流的文件结束指示符并且存在下一个字符,则
醇>fgetc
函数会将该字符转换为unsigned char
转换为{ {1}}并提升流的关联文件位置指示符(如果已定义)。<强>返回强>
- 如果设置了流的文件结束指示符,或者流位于文件结尾,则设置流的文件结束指示符并返回
醇>int
函数fgetc
。否则,EOF
函数返回stream指向的输入流中的下一个字符。如果发生读取错误,则设置流的错误指示符,fgetc
函数返回fgetc
。 [289]
由于这是EOF
转换为unsigned char
,int
几乎总是与unsigned char具有相同的值。
对于int
的某些平台上的高值,可能不是这样;然而,这些主要是DSP平台,因此几乎可以肯定在这些平台上不需要进行字符分类。
sizeof(int) == 1
函数经过精心定义,因此可以直接使用is*
C11 7.4p1的返回值:
1标题
*getc*
声明了几个对字符分类和映射有用的函数。 [198]在所有情况下,论证都是<ctype.h>
,其值应表示为int
或应等于宏的值unsigned char
。如果参数具有任何其他值,则行为未定义。
即。将EOF
传递给EOF
函数是合法的。当然is*
将始终返回0,因此要计算连续空格字符,可以使用以下内容:
isanything(EOF)
但是,签名的char值不正常,例如,如果将while (isspace(getchar())) space_count ++;
以外的负值传递给任何字符分类,则 abort 已知MSVC C调试库功能