C标准是否指定了从stdout读取输入的行为?

时间:2016-04-29 06:33:14

标签: c

以下计划:

#include <stdio.h>

int main()
{
    char s[10] = "";
    fprintf(stdout, "%s", "hello");
    fscanf(stdout, "%6s", s);
    perror(NULL);
}

输出Bad file descriptor。但是C11 draft standard的第7.21节似乎没有说明是否允许将stdout传递给fscanf。这是未定义的行为吗?明确(给出标准引用)或暗示(通过省略)?

2 个答案:

答案 0 :(得分:4)

规范(ISO / IEC 9899:2011(E),§7.21)实际上没有提到对传递给输出函数的输入流或传递给输入函数的输出流的任何限制。规范中唯一的限制是传递给getFullPath()的流必须是输出流。

答案 1 :(得分:2)

§4/ 2(引用WG14 N1570):

  

本国际上另有说明未定义的行为   标准用“未定义的行为”或“遗漏任何行为”   行为的明确定义。

§7.21.3/ 11

  

字节输入函数从流中读取字符,就像是   连续调用fgetc函数。

fscanf是字节输入函数;§7.2.1/ 5)。

§7.21.7.1:

  

fgetc功能

     

<强>概要

#include <stdio.h>
int fgetc(FILE *stream);
     

<强>描述

     

2 如果指向输入流的文件结束指示符   未设置到stream,并且存在下一个字符fgetc   function将该字符转换为unsigned char转换为   int并提升相关文件位置指示器   流(如果已定义)。

     

<强>返回

     

3 如果设置了流的文件结束指示符,或者如果设置了   流位于文件结尾,即流的文件结束指示符   已设置,fgetc函数返回EOF。否则,fgetc   function返回指向的输入流中的下一个字符   按stream。如果发生读取错误,则为错误指示   设置了流,fgetc函数返回EOF。 [脚注省略]

fgetc的规范反复说“stream指向的输入流”;在我看来,这可以通过两种方式阅读:要么隐含要求stream指向输入流,要么标准省略指定stream未指向任何行为时输入流。

在第一种情况下,将非输入流传递给fgetc违反了该要求并且是未定义的行为(另见§7.1.4/ 1;有人可能认为这算作“域外的值”功能“);在第二种情况下,通过省略将非输入流传递给fgetc是未定义的行为,因为该标准没有说明fgetc在这种情况下的行为。所以我认为fgetc(not_an_input_stream)会导致未定义的行为。

如果fgetc(not_an_input_stream)是未定义的行为,那么fscanf(not_an_input_stream, /*...*/)也是如此,因为后者被指定为通过调用前者来读取字符。