FILE *stdout 和 STDOUT_FILENO 的区别

本文解析了标准输入输出(stdin/stdout)与文件描述符(STDIN_FILENO/STDOUT_FILENO)的区别及其使用场景,通过示例代码展示了如何利用freopen函数改变标准输出的目标。

转自:http://blog.sina.com.cn/s/blog_9f1496990100y3st.html

首先要知道 FILE *stdout 和 STDOUT_FILENO 的区别。
stdin类型为 FILE*
STDIN_FILENO类型为 int
使用stdin的函数主要有:fread、fwrite、fclose等,基本上都以f开头
使用STDIN_FILENO的函数有:read、write、close等
操作系统一级提供的文件API都是以文件描述符来表示文件。STDIN_FILENO就是标准输入设备(一般是键盘)的文件描述符。
标准C++一级提供的文件操作函数库都是用FILE*来表示文件,stdin就是指向标准输入设备文件的FILE*。
如下:

参考stdin(3)的man手册:
Name
stdin, stdout, stderr - standard I/O streams
Synopsis
#include <stdio.h>
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;
...
On program startup, the integer file descriptors associated with the streams stdin, stdout, and stderr are 0, 1, and 2, respectively. The preprocessor symbols STDIN_FILENO, STDOUT_FILENO, and STDERR_FILENO are defined with these values in <unistd.h>. (Applying freopen(3) to one of these streams can change the file descriptor number associated with the stream.)
...

stdin / stdout / stderr
分别是指向stream的FILE型的指针变量。
当程序启动时,与其结合的整型文件描述符(fd)分别是0,1,2。

STDIN_FILENO / STDOUT_FILENO / STDERR_FILENO
是在

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

#define CHANGE_BY_FREOPEN

int main(int argc,char**argv){
char buf[]="hello,world\n";

#ifdef CHANGE_BY_FREOPEN
freopen("stdout_text.txt","w",stdout);
//freopen("stderr_text.txt","w",stderr);
#endif

printf("%s",buf);
fwrite(buf,strlen(buf), 1,stdout);
write(STDOUT_FILENO,&buf,strlen(buf));
perror("error out");

return(0);
}

编译命令,生成可执行文件 stdouttest

$ gcc -o stdouttest stdouttest.c


当 #define CHANGE_BY_FREOPEN 被注释掉,无效的时候:
终端shell窗口中的输出结果是:

$ ./stdouttest
hello,world
hello,world
hello,world
error out: No error
$

注:
3个(hello,world + 换行符)。
1个error的输出
标准输入输出,都还是shell窗口。


当 #define CHANGE_BY_FREOPEN ,有效的时候:
终端shell窗口中的输出结果是:

$ ./stdouttest
error out: No error
$

注:shell窗口中,仅有stderr的输出。

但是,会创建一个名为stdout_text.txt的文件,
该文件中的内容是:
hello,world
hello,world
hello,world

注:
3个(hello,world + 换行符)。
仅标准输出,从shell窗口,改变为stdout_text.txt的文件了。

//freopen(“stderr_text.txt”,”w”,stderr);
如果有效的话:
①shell中,什么也不输出。
②stdout_text.txt 中,输出3个(hello,world + 换行符)。
③stderr_text.txt 中,输出1个(error out: No error)。

0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 getaddrinfo 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 timegm 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 difftime 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 getnameinfo 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 nanosleep 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 strncat 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 unlink 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 strcspn 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 shm_open 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 fgets 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 ftruncate 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 sendto 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 __libc_start_main 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 pthread_mutex_lock 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 sigfillset 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 epoll_ctl 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 clock_gettime 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 localtime 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 time 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 recvfrom 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 fileno 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 readdir 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 rename 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 strtod 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 atoi 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 inet_aton 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 qsort 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.33 fstat 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 readlink 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 getpid 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 socket 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 pselect 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 snprintf 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 strcat 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 strncasecmp 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 putchar 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 fseeko 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 pthread_exit 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 fprintf 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 sigaction 0000000000000000 DO *UND* 0000000000000000 GLIBC_2.17 __stack_chk_guard 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 memcpy 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 htons 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 __ctype_b_loc 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 fread 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 gethostbyname 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 strncpy 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 exit 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 cos 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 munmap 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 ftello 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 strftime 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 strrchr 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 localtime_r 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 mktime 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 select 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 tcdrain 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 __cxa_atexit 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 sync 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 sleep 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 shutdown 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 gmtime 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 strstr 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 shmat 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 _exit 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 ntohs 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 pclose 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 getsockopt 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 mmap 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 secure_getenv 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 fputc 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 clock 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 closedir 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 __isoc99_sscanf 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 strncmp 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 mq_open 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 inet_pton 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 abort 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 pthread_join 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 __isoc99_fscanf 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 strspn 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 __sigsetjmp 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 usleep 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 ferror 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 fgetc 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 uname 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 fflush 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 pthread_setname_np 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 pthread_mutex_destroy 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 remove 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 __assert_fail 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.25 getrandom 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 __errno_location 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 freeaddrinfo 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 recv 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 read 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 mprotect 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 sigprocmask 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 perror 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 signal 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 strtoll 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 mlock 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 syscall 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 siglongjmp 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 shmdt 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 fopen 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 mq_send 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 tolower 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 listen 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 __stack_chk_fail 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 inet_ntop 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 write 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 mq_close 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 socketpair 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 vprintf 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 rand 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 cfgetospeed 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 __getauxval 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 poll 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 gai_strerror 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 feof 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 memcmp 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 fseek 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 pthread_cancel 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 mq_unlink 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 send 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 cfsetispeed 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 bind 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 pthread_mutex_init 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 fclose 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 ioctl 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 strtoul 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 setvbuf 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 getpeername 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 pthread_create 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 pthread_mutex_unlock 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 epoll_create1 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 strtol 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 sqrt 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 tcgetattr 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 sin 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 opendir 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 strdup 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 calloc 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 getenv 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 vsnprintf 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 popen 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 setsockopt 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 mq_receive 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 gettimeofday 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 strchr 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 mkdir 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 __xpg_strerror_r 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 getauxval 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 memchr 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 sysconf 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 accept 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 shmget 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 cfsetospeed 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 reboot 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 atan2 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 puts 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 tcsetattr 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 epoll_wait 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 sched_yield 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 strerror 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 sprintf 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 pthread_testcancel 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 fwrite 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 madvise 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 inet_addr 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 sigdelset 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 fputs 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 printf 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 strcpy 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 freopen 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 memmove 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 close 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 vfprintf 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 connect 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.33 stat 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 __ctype_tolower_loc 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 strlen 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 fopen64 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 ftell 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 fcntl 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 utime 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 pthread_self 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 shm_unlink 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 srand 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 open 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 getsockname 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.17 memset 00000000007b2560 g DO .bss 0000000000000008 GLIBC_2.17 stdout 0000000000403c60 DF *UND* 0000000000000000 GLIBC_2.17 realloc 0000000000000000 w DF *UND* 0000000000000000 GLIBC_2.25 getentropy 00000000007b2568 g DO .bss 0000000000000008 GLIBC_2.17 stderr 00000000007b2570 g DO .bss 0000000000000008 GLIBC_2.17 stdin 0000000000404130 DF *UND* 0000000000000000 GLIBC_2.17 malloc 00000000004043b0 DF *UND* 0000000000000000 GLIBC_2.17 free 0000000000404220 DF *UND* 0000000000000000 GLIBC_2.17 strcmp 0000000000404520 DF *UND* 0000000000000000 GLIBC_2.17 strcasecmp
最新发布
11-21
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值