在C语言中,
stdin
和STDIN_FILENO
有什么实际区别(如果有的话)?stdin
和STDIN_FILENO
有什么实际区别(如果有的话)?stdin
是标准c库定义的FILE *
。您可以使用一些更高级别的接口,例如fread
、fwrite
和fprintf
。另一方面,STDIN_FILENO
只是一个文件描述符(几乎肯定为0)。这使用了稍微低级别的接口,例如read
和write
。STDIN_FILENO
是在<unistd.h>
中定义的宏。至少对于符合POSIX标准的系统来说,它不只是“几乎肯定为0”,而是必须被定义为0。同样地,STDOUT_FILENO
为1,STDERR_FILENO
为2。 - Keith Thompson<unistd.h>
头文件和两个常量 STDIN_FILENO
和 STDOUT_FILENO
都是 POSIX 标准的一部分。此头文件包含许多 UNIX 系统服务的函数原型,例如我们调用的 read
和 write
函数。STDIN_FILENO
和 STDOUT_FILENO
常量被定义在 <unistd.h>
中,并指定标准输入和标准输出的文件描述符。这些值分别为0和1,符合 POSIX.1 的规定,但为了可读性,我们使用名称。 --来源:《Unix高级编程》第2版第9页 - Nabil Kadimistdin
是一个默认的FILE指针,用于从标准输入中获取输入。
STDIN_FILENO
是默认的标准输入文件描述符号,它是0
。它本质上是用于通用目的的定义指令。
从/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;
}
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;
}
./command < some_file
不会创建一个管道。你可以通过获取管道大小来检查它是否为管道:在这种情况下,fcntl(STDIN_FILENO, F_GETPIPE_SZ)
返回 -1
。当stdin是一个管道时(cat some_file | ./command
),相同的调用返回 65536
(或另一个正整数,因人而异)。 - Eric