技术的乐趣在于分享,欢迎多多交流,多多沟通。
全部博文(877)
分类: 嵌入式
2014-09-02 11:20:48
将信息输出到文件,有多种办法,一般常用的方法为: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标准库里面是没有办法的。
很容易想到的方式是重新打开标准控制台设备文件,但遗憾的是,这个设备文件的名字是操作系统相关的。
给个参考: 并不一定好用,至少我的电脑上不好用。
再来看第二种方法,
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上实测是没有问题的,比较好用。