isspace()是否接受getchar()值?

问题描述 投票:3回答:2

如果输入是isspace()或等于representable as unsigned char,则EOF有效。

getchar()从stdin读取下一个字符。

getchar()!=EOF;所有getchar()返回值可以表示为unsigned char

uintmax_t count_space = 0;
for (int c; (c = getchar()) != EOF; )
  if (isspace(c))
    ++count_space;

愿这段代码导致未定义的行为吗?

c language-lawyer c11
2个回答
10
投票

根据C11 WG14 draft version N1570

§7.21.7.6/ 2 getchar函数等效于带有参数stdin的getc

§7.21.7.5/ 2 getc函数相当于fgetc ...

§7.21.7.1/ 2 [!=EOF案例] ...... fgetc函数获得该字符作为unsigned char转换为int ... [...]中的文本是我的。

即,

  • isspace()接受getchar()
  • 所有getchar()!=EOF值都可以表示为unsigned char
  • 这里没有未定义的行为。

如果你认为它太明显了(“它还能做什么”),那就再想一想。例如,在the related case中:isspace(CHAR_MIN)可能未定义,即,将字符传递给字符分类函数可能是未定义的行为!

如果UCHAR_MAX > INT_MAX结果可能是实现定义的:

§6.3.1.3/ 3否则,新类型已签名,其值无法表示;结果是实现定义的,或者引发实现定义的信号。


1
投票

getchar()的返回值与fgetc()的格式相同。 C11定义了fgetc()7.21.7.1p2-3的返回值:

  1. 如果没有设置stream指向的输入流的文件结束指示符并且存在下一个字符,则fgetc函数将该字符作为unsigned char转换为int并推进该流的相关文件位置指示符(如果定义)。

返回

  1. 如果设置了流的文件结束指示符,或者流位于文件结尾,则设置流的文件结束指示符,并且fgetc函数返回EOF。否则,fgetc函数返回stream指向的输入流中的下一个字符。如果发生读取错误,则设置流的错误指示符,并且fgetc函数返回EOF。 [289]

由于这是一个unsigned char转换为intint几乎总是与unsigned char具有相同的值。

在某些sizeof(int) == 1平台上的高值可能不是这样;然而,这些主要是DSP平台,因此几乎可以肯定在这些平台上不需要进行字符分类。


is*函数经过精心定义,因此可以直接使用*getc* C11 7.4p1的返回值:

1标题<ctype.h>声明了几个对字符分类和映射有用的函数。 [198]在所有情况下,论证都是int,其值应表示为unsigned char或等于宏EOF的值。如果参数具有任何其他值,则行为未定义。

即将EOF传递给is*函数是合法的。当然isanything(EOF)将始终返回0,因此要计算连续的空白字符,可以使用以下内容:

while (isspace(getchar())) space_count ++;

但是,有符号的char值不正常,例如,如果将EOF以外的负值传递给任何字符分类函数,则已知MSVC C调试库将中止。

© www.soinside.com 2019 - 2024. All rights reserved.