按照惯例,UNIX系统shell使用文件描述符0与进程的标准输入(一般是键盘)相关联,文件描述符1与标准输出(一般是显示器)相关联,文件描述符2与标准出错输出(一般是显示器)相关联。

在依从POSIX的应用程序中,幻数0、1、2应当替换成符号常量STDIN_FILENO、STDOUT_FILENO和STDERR_FILENO。这些常量都定义在头文件<unistd.h>中。

一般在教材中不会明确区分,但是我们应注意到标准输入有两层含义:一是指STDIN_FILENO(惯例指定的标准输入设备描述符);另一层含义则是指标准输入设备(如键盘)。同样,标准输出也有两层含义:一是指STDOUT_FILENO(惯例指定的标准输出设备描述符);另一层含义则是指标准输出设备(如显示器)。

scanf函数从标准输入读取内容,我们通常会认为是从键盘读取的。printf函数把内容输出到标准输出,我们通常认为是输出到显示器上。这并没有问题,但前提是“在通常情况下”。

精确地说,scanf函数是从文件描述符STDIN_FILENO(0)所关联的文件中读取,而prinf函数则是输出到文件描述符STDOUT_FILENO(1)所关联的文件中。

如果STDIN_FILENO关联的文件不是键盘,那么scanf就不会从键盘读取内容,同理,如果STDOUT_FILENO关联的文件不是显示器,那么printf也不会将内容输出到显示器。

举例说明(不深究此程序片段意义如何,只为说明上面的叙述而用):

...
int fd[2];
int pid; pipe(fd); if((pid = fork()) < 0)
{
perror("fork");
exit(1);
}
else if(pid == 0) /* 子进程 */
{
close(fd[0]);
dup2(fd[1], STDOUT_FILENO);
...
}
else /* 父进程 */
{
close(fd[1]);
dup2(fd[0], STDIN_FILENO);
...
}

子进程中,如果在dup2(fd[1], STDOUT_FILENO); 语句后调用printf函数,那么内容并不会输出到显示器,而是写入了管道中。

父进程中,如果在dup2(fd[0], STDIN_FILENO); 语句后调用scanf函数,那么不会从键盘读取内容,而是从管道中读取。

清楚地了解标准输入和标准输出在特定上下文中的确切含义,有时可以避免不必要的困扰。

最新文章

  1. 【算法杂谈】Miller-Rabin素性测试算法
  2. iOS----Xcode6或者Xcode7设置LaunchImage图标
  3. linux安装软件通常会做哪些事
  4. codeforces733D. Kostya the Sculptor 偏序cmp排序,数据结构hash,代码简化
  5. cdr创建样式与样式集的方法
  6. 【转】C#绝对新手之C#中的多线程小结
  7. js 拼接 三列做为一行
  8. JSON数据与JavaScript对象转换
  9. 获取第下一个兄弟元素 屏蔽浏览器的差异(nextElementsibling)
  10. Java:Java快速入门
  11. C#加密与解密
  12. apache本地多域配置(wampserver本地多域配置)
  13. Struts2.5 利用Ajax将json数据传值到JSP
  14. 百度URL 部分参数
  15. react dnd demo2
  16. Vue技术内幕 出去看看吧 榨干部分小细节
  17. laravel passport加密jwt格式的access_token中的sub(user_id)字段
  18. vuex状态管理
  19. Spring Cloud Eureka 属性作用
  20. php插入上万条mysql数据最快的方法

热门文章

  1. Eclipse配置信息
  2. 服务器多块磁盘 ,同时磁盘类型混合(SSD+STAT+SAS)
  3. UVALive 5888 Stack Machine Executor (栈+模拟)
  4. LC串联谐振回路
  5. 【破解三网】iphone5 国行 A1429
  6. TPARAMS和OLEVARIANT相互转换
  7. SOA和Web Service介绍
  8. mysql中key 、primary key 、unique key 与index区别
  9. 在jybot下跑Selenium2Library
  10. 前端MVC学习总结(三)——AngularJS服务、路由、内置API、jQueryLite