【问题标题】:Where to find `stdin` macro declaration? [duplicate]在哪里可以找到“stdin”宏声明? [复制]
【发布时间】:2018-05-06 08:34:54
【问题描述】:

我一直在尝试在我的模块中编写“简单易用”的输出重定向。它假设在某个文件和stdin 之间更改fprintf 的输出。 所以我一直在考虑类似的事情:

    void _connection(char mode) {   /* pass 'v' as an argument to set verbous mode*/
      FILE *stream

      if (mode == 'v')
        fopen(stream, "stdin location?");
      else
        fopen(stream, "../stream");

      fprintf(stream, "Connecting to the queue...");
      ...
      fprintf(stream, "Some detail information...");
      ---

搜索我的系统我找不到任何标准输入声明。我系统上的stdio.h 源文件正在使用这个宏,但我无法从哪里得到它。我的意思是,此文件中没有输入文件或任何名为 stdin 的宏。

【问题讨论】:

  • @EugeneSh。视情况而定。
  • @iBug 是的,它可能是宏。删除评论

标签: c printf stdin stdio


【解决方案1】:

在这里找到它(Unix):

/usr/include/stdio.h

或者在 Windows 上:

(Compiler Path)\include\stdio.h

请注意,ISO C 标准要求 stdin/stdout/stderr 是宏,而 POSIX 要求它们是外部 FILE* 标识符,因此您可能会在符合 POSIX 的系统(Linux 和其他):

#define stdin stdin

【讨论】:

  • C 标准(任何版本)要求它们是宏,“它们是类型为 ''pointer to FILE'' 的表达式,分别指向与标准错误关联的 FILE 对象,输入,并输出流。”
  • POSIX 避免与 C 标准相矛盾,并且也需要宏:<stdio.h> 标头应定义以下宏,这些宏应扩展为指向 FILE 的“指向文件的指针”类型的表达式分别与标准错误、输入和输出流相关联的对象:stderr 标准错误输出流。 stdin 标准输入流。 stdout 标准输出流。。没有什么能阻止宏成为 #define stdin stdin 等。在 Mac 上,它们被映射到内部名称:#define stdin __stdinp
【解决方案2】:

stdin 宏在 stdio.h 或它最终包含的文件中定义。只要您#include <stdio.h>,您就可以访问它。

对于您正在执行的操作,您无需执行单独的打开操作。只需将stdin 复制到您的文件指针:

  if (mode == 'v')
    stream = stdin;
  else
    fopen(stream, "../stream");

【讨论】:

  • 不,stdin 宏在 stdio.h 中定义,句号。这是由 7.21.1 明确指定的。
  • @Lundin 如果<stdio.h> 标头完全由#include <bits/stdio.h> 组成,并且定义了stdin,那么我认为这符合<stdio.h> 定义stdin 的条件。
  • 但是,当涉及到fclose(stream) 时,如果您之前设置了stream = stdin;,您可能希望避免这样做。
  • @DanielH 该标准明确指出 stdin 是一个宏,在 stdio.h 中定义。这没什么好争论的,C11 7.21.1。至于宏的内容,很可能是外部指针变量声明之类的东西。
  • 我并不是在争论它是一个宏。我是说“标头 <stdio.h> 定义了几个宏”这句话并不意味着在文件系统的某处有一个名为 stdio.h 的文件,其中有一个 #define<stdio.h> 的内容可能在一个不名为 stdio.h 的文件中,或者它们可能不在任何文件中,而是硬编码到编译器中或动态生成。见 6.10.2p2。如果实现将“头文件的全部内容”定义为“文件/usr/include/stdio.h 的预处理内容”,那么该文件可以包含它自己的定义宏的文件。