注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

多多的爹

 
 
 

日志

 
 

读程序,学习Linux编程(十三)  

2010-08-19 19:12:08|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

3.6. stdin,stdout,stderr

接下来看188行:

188 fprintf(stderr,

189 "%s: Could not allocate memory.\n",

190 argv[0]);

学习C语言的时候,我们就知道用printf打印字符串,其实这个函数有一个函数族,形式差不多,我们来看看:

#include

int printf(const char *format, ...);

int fprintf(FILE *stream, const char *format, ...);

int sprintf(char *str, const char *format, ...);

int snprintf(char *str, size_t size, const char *format, ...);

怎么用不介绍了,不会的找本谭浩强《C语言设计》看看,看完了还不会的,再去写100行测试代码,基本上就会用了。我们要谈的,是stderr这个东西。

stderr表示错误处理变量,他有两个哥哥,stdin和stdout,前者表示输入处理变量,后者表示输出处理变量。这三个变量已经为我们的程序准备好(我也说不清楚是C语言准备的,还是操作系统准备的),在代码里可以直接使用他们,跟操作文件没什么两样。他们各自有一些特殊性,需要了解。stdin只能用来读,我们可以把它当作终端的输入,当你在终端上输入文字后并回车,我们就可以从stdin中讲到刚刚输入的文字了,比如用函数fread,fgetc等。stdout只能写,它将我们写入的数据,显示到终端中,比如用函数fwrite,fputs等。stderr也只能写,我的个人感觉它跟stdout差不多,都是在终端中写入,只不过因为名字不同,其内涵则表示为输出的是一条错误信息。

上面介绍了这三个常量,后面介绍一点与它们相关的其它内容。

先介绍一下Linux的文件操作。文件被打开后,会被分配一个文件描述符,文件描述符是一个整数,我们通过这个文件描述符来读写它,用完后再关闭。

Linux将大部分设备,都当成文件来处理。终端也是一种设备,也同样可以打开和读写。通常不需要自己打开关闭终端。Linux已经为每个进程准备好了终端设备的文件描述符,分别是stdin,stdout和stderr。可以用ctal+]查看一下stdin的声明,在/usr/include/stdio.h中我们找到下面的代码:

144 /* Standard streams. */

145 extern struct _IO_FILE *stdin; /* Standard input stream. */

146 extern struct _IO_FILE *stdout; /* Standard output stream. */

147 extern struct _IO_FILE *stderr; /* Standard error output stream. */

148 /* C89/C99 say they're macros. Make them happy. */

149 #define stdin stdin

150 #define stdout stdout

151 #define stderr stderr

struct _IO_FILE我们不太熟悉,在stdio.h中,把光标跳转到49行:

49 typedef struct _IO_FILE FILE;

看到FILE,是不是想了什么?是的,fopen打开文件后,保存的结果就是我们熟悉的FILE。

不过,我们前面提到过,文件描述符应该是整数,怎么成了一个结构体?其实这是一回事,open,read,write和close是系统提供的api函数,而fopen,fread,fwrite和fclose是C语言库提供文件操作封装函数。将下面代码编译后运行:

printf("%d %d %d\n", stdin->_fileno, stdout->_fileno, stderr->_fileno);

输出结果很简单:

0 1 2

是的,stdin,stdout,stderr对应的文件描述符就是0,1,2。你在代码里直接read文件0和直接write文件1,跟用fread stdin和fwrite stdout是一样的效果。

Linux中,文件的描述符分配是从小到大挨个来的。我们做下面这个测试:

main()

{

char buf[BUFSIZ] = {0};

strcpy(buf, "Now you can see me.\n");

write(1, buf, strlen(buf) + 1);

close(1);

int fd = open("test", O_CREAT | O_TRUNC | O_WRONLY);

sprintf(buf, "Now you can not see me and my file discription is %X\n", fd);

write(1, buf, strlen(buf) + 1);

close(fd);

}

程序首先直接用write在文件描述符1中输出一行文字,然后关闭文件描述符1。接着用open创建一个文件,然后再往文件描述符1中写入一段文字。

编译后运行,看到屏幕上只输出前面那段话。打开文件test,能看到第二段文字了,并且发现文件描述符就是1。

  评论这张
 
阅读(3)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017