原创 标准输出stdout重定向至文件 [原创]

2009-9-4 12:01 6259 8 9 分类: 软件与OS

将信息输出到文件,有多种办法,一般常用的方法为:fprintf,stdout重定向。对于fprintf,由于参数中有文件句柄,如果原有软件是基于printf开发的,就改动较大了,要查找、替换,得费不少功夫。所以我着重研究了一下stdout标准输出流的重定向问题。


这里先扯一点概念问题吧:


     流是程序输入或输出的一个连续的字节序列,设备(例如鼠标、键盘、磁盘、屏幕、调制解调器和打印机)的输入和输出都是用流来处理的。在C语言中,所有的流均以文件的形式出现----不一定是物理磁盘文件,还可以是对应于某个输入/输出源的逻辑文件。C语言提供了5种标准的流,你的程序在任何时候都可以使用它们,并且不必打开或关闭它们。以下列出了这5种标准的流。
------------------------------------------------
    名称          描  述            例  子
------------------------------------------------
    stdin        标准输入           键盘
    stdout       标准输出            屏幕
    stderr       标准错误            屏幕
    stdprn       标准打印机          LPT1端口
    stdaux       标准串行设备        COM1端口
------------------------------------------------
    需要注意的是,stdprn和stdaux并不总是预先定义好的,因为LPT1和COM1端口在某些操作系统中是没有意义的,而stdin,stdout和stderr总是预先定义好的。此外,stdin并不一定来自键盘,stdout也并不一定显示在屏幕上,它们都可以重定向到磁盘文件或其它设备上。


 


这里主要讨论stdout流的重定向问题,主要有两种方法:


1)利用freopen实现;


2)   利用_dup实现;


还是先看看第一种方法吧,稍简单一些,实例代码如下:


FILE *stream;
void main( void )
{
   stream = freopen( "freopen.out", "w", stderr ); // 重定向

  if( stream == NULL )
     fprintf( stdout, "error on freopen\n" );
  else
  {
     fprintf( stream, "This will go to the file 'freopen.out'\n" );
     fprintf( stdout, "successfully reassigned\n" );
     fclose( stream );
  }
  system( "type freopen.out" );
}


但并不存在一个完全兼容的解决方案能够在以后将标准句柄恢复。在C标准库里面是没有办法的。
很容易想到的方式是重新打开标准控制台设备文件,但遗憾的是,这个设备文件的名字是操作系统相关的。


给个参考: 并不一定好用,至少我的电脑上不好用



  • 在DOS/Win中,这个名字是CON,因此可以使用
    freopen("CON", "r", stdin)


  • 在linux中,控制台设备是 /dev/console
    freopen("/dev/console", "r", stdin)

再来看第二种方法,


void main( void )
{
   int old;
   FILE *new;
   old = _dup( 1 );   // 取标准输出句柄
   if( old == -1 )
   {
      perror( "_dup( 1 ) failure" );
      exit( 1 );
   }
   write( old, "This goes to stdout first\r\n", 27 );
   if( ( new = fopen( "data", "w" ) ) == NULL )
   {
      puts( "Can't open file 'data'\n" );
      exit( 1 );
   }
   if( -1 == _dup2( _fileno( new ), 1 ) )
   {
      perror( "Can't _dup2 stdout" );
      exit( 1 );
   }
   puts( "This goes to file 'data'\r\n" );
   fflush( stdout );
   fclose( new );
   _dup2( old, 1 ); // 恢复
   puts( "This goes to stdout\n" );
   puts( "The file 'data' contains:" );
   system( "type data" );
}


这个在XP上实测是没有问题的,比较好用。

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

huotingtu_505472073 2009-9-10 10:48

恩 学习了 ,很有用
相关推荐阅读
walnutcy_696810119 2012-11-21 08:37
Linux下使用smartCOM调试串口
在Windows下的串口调试一直使用sscom,在Linux下只找到一个cutecom,用了几次,很不喜欢,就着手开发了一款自己的串口调试工具,smartCOM。 smartCOM介绍:http...
walnutcy_696810119 2012-03-29 18:12
【博客大赛】原创--测量基础:什么是测量
写在正文之前: 适逢EDNChina搞活动,而我本人也算在测量业工作,就一起作下笔记吧。若有错误,请大家一起斧正。笔者写本文一方面是梳理知识,另一方面也希望与大家探讨有关测量的知识、应用等,希...
walnutcy_696810119 2011-12-20 18:29
GLONASS 15年来,首次实现24颗星在轨可用
  EDN的博客改版后,不太好用,在SINA重开一个,不过重点改为关注GNSS行业新闻 http://blog.sina.com.cn/s/blog_7420cd1701012en9....
walnutcy_696810119 2011-12-20 17:49
逆向工程第一步:通信协议分析
工程中常有这样的事,想分析下其他知名公司产品中的通信协议,以便生产设计兼容产品。 1) 逆向工程,首先要了解产品,知己知彼,百战不怠;     去年受命想仿一款GARMIN的导航盒,但无法...
walnutcy_696810119 2011-11-14 11:30
通用代码调试方法 (Keil, VCC)
调试代码一般需要定位问题,这里给出一个解决方案, 一般的编译器均支持这些宏指令。   #define DEBUG_WALT_1113     1 extern void log_t...
EE直播间
更多
我要评论
1
8
关闭 站长推荐上一条 /3 下一条