stdin和STDIN_FILENO之间有什么区别?

59
在C语言中,stdinSTDIN_FILENO有什么实际区别(如果有的话)?

2
一个有趣的讨论话题:http://www.rtems.com/ml/rtems-users/2011/march/msg00101.html。或许你也应该问一下为什么`fileno(stdin)`和`STDIN_FILENO`不同。 - user7116
1
@user7116,很抱歉你的链接已经失效了。 - Jonathon Reinhart
1
@pixelbeat,你的链接也失效了 :( 有没有一个关于这个主题的信息丰富的阅读材料? - user2469227
1
最新链接似乎是:https://lists.rtems.org/pipermail/users/2011-March/023277.html - David Arnold
6
我会彻底解决这件事情:https://web.archive.org/web/20180127193256/https://lists.rtems.org/pipermail/users/2011-March/023277.html - lvella
显示剩余3条评论
5个回答

69
接口。正如其他人所说,stdin是标准c库定义的FILE *。您可以使用一些更高级别的接口,例如freadfwritefprintf。另一方面,STDIN_FILENO只是一个文件描述符(几乎肯定为0)。这使用了稍微低级别的接口,例如readwrite

39
所有的答案都没有提到STDIN_FILENO是在<unistd.h>中定义的宏。至少对于符合POSIX标准的系统来说,它不只是“几乎肯定为0”,而是必须被定义为0。同样地,STDOUT_FILENO为1,STDERR_FILENO为2。 - Keith Thompson
1
<unistd.h>头文件和两个常量 STDIN_FILENOSTDOUT_FILENO 都是 POSIX 标准的一部分。此头文件包含许多 UNIX 系统服务的函数原型,例如我们调用的 readwrite 函数。
STDIN_FILENOSTDOUT_FILENO 常量被定义在 <unistd.h>中,并指定标准输入和标准输出的文件描述符。这些值分别为0和1,符合 POSIX.1 的规定,但为了可读性,我们使用名称。 --来源:《Unix高级编程》第2版第9页
- Nabil Kadimi

26
"

stdin是一个默认的FILE指针,用于从标准输入中获取输入。

STDIN_FILENO是默认的标准输入文件描述符号,它是0。它本质上是用于通用目的的定义指令。

"

13

/usr/include/stdio.h中:

/* Standard streams.  */
extern struct _IO_FILE *stdin;          /* Standard input stream.  */
extern struct _IO_FILE *stdout;         /* Standard output stream.  */
extern struct _IO_FILE *stderr;         /* Standard error output stream.  */
/* C89/C99 say they're macros.  Make them happy.  */
#define stdin stdin
#define stdout stdout
#define stderr stderr

来自/usr/include/unistd.h

/* Standard file descriptors.  */
#define STDIN_FILENO    0       /* Standard input.  */
#define STDOUT_FILENO   1       /* Standard output.  */
#define STDERR_FILENO   2       /* Standard error output.  */

例如,stdin (_IO_FILE/usr/include/libio.h 中定义) 是一个结构体数据。 STDIN_FILENO 是一个宏常量,它指向内核使用的文件描述符。

#include <stdio.h>
#include <unistd.h>

void
stdin_VS_STDIN_FILENO(void)
{
    printf("stdin->_flags = %hd\n", stdin->_flags);
    printf("STDIN_FILENO  : %d\n", STDIN_FILENO);
}

int
main(void)
{
    stdin_VS_STDIN_FILENO();
    return 0;
}

你介意解释一下最后那段代码片段的作用吗? - undefined

2

stdin:1. 文件指针 (* FILE) 2. 进程创建时,文件描述符表保存其地址。 3. 在 /usr/include/stdio.h 中存在。

STDIN_FILENO:1. 它是一个宏 2. 它仅是文件描述符表的数组索引(默认为 0)。 3. 在 /usr/include/unistd.h 中存在。

以下代码可使上述内容更加清晰。

#include<stdio.h> 
#include<unistd.h> 
int main() 
{    
     printf("%d\t\t%p ----- ",STDIN_FILENO,stdin);

return 0; 
} 

0
在Linux头文件#include "unistd.h"中,STDIN_FILENO只是一个代表管道stdin的宏,其值为0。当您使用Linux管道时,可以使用该宏。

你说得没错,但是(挑刺)管道与此无关。标准输入并不总是一个管道,例如在bash中 ./command < some_file 不会创建一个管道。你可以通过获取管道大小来检查它是否为管道:在这种情况下,fcntl(STDIN_FILENO, F_GETPIPE_SZ) 返回 -1。当stdin是一个管道时(cat some_file | ./command),相同的调用返回 65536(或另一个正整数,因人而异)。 - Eric

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接