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

时间:2017-11-05 07:07:20

标签: c language-lawyer c11

如果输入为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;

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

2 个答案:

答案 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-3fgetc()的返回值:

  
      
  1. 如果未设置stream指向的输入流的文件结束指示符并且存在下一个字符,则fgetc函数会将该字符转换为unsigned char转换为{ {1}}并提升流的关联文件位置指示符(如果已定义)。
  2.         

    <强>返回

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

由于这是EOF转换为unsigned charint 几乎总是与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调试库功能