【转载】标准输入输出重定向(Visual C++)
引言
本人偶得在 Visual C++ 中进行输入输出重定向的办法,比通常的做法“freopen”更加的灵活和方便,特在此共享。目前,代码正在不断地摸索和完善中,先把“输出”(stdout)部分提供给大家。
阅读本文需要有一定的 Visual C++ 开发经验。本文所介绍的内容,只适用于一些特殊需求,不知道“输出重定向”有什么用的朋友,不必感到迷茫。
1. 简介
在 Visual C++ 中,有好几种用法与标准输入输出有关:
系列1:scanf,printf,fprintf(stderr,...)……
系列2:cin,cout,cerr……
系列3:GetStdHandle,SetStdHandle……
使用 MSDN 所介绍“freopen”的方法,能够将以上 3 种输出,都重定向到文件中。但这种用法不是很灵活,如果不是要输出到文件,而是要将输出的内容直接进行处理就不是很方便。
本人经过摸索,现可以将 <stdio.h> 中的 stdout、stderr;<iostream.h> 中的 cout、cerr、clog;<winbase.h> 中的 STD_OUTPUT_HANDLE、STD_ERROR_HANDLE 各自重定向到不同的地方,并且还支持一种特殊的重定向:重定向到回调函数(Callback Function),特在此共享。
2. 功能讲解
本次提供的功能,方法名叫做 RedirectStdout,传递给它的参数主要有 4 个:
- 哪些输出要被重定向。比如:指定 (stderr | cout) ,那么其他的输出仍然输出到屏幕。
- 重定向到哪里。比如:重定向到文件,还是到屏幕,还是到回调函数。
- 文件名。如果是重定向到文件,则需要指定文件名。
- 回调函数。如果是重定向要回调函数,则需要指定回调函数。
接口头文件:
// 可能的输出,用在第一个参数(可组合使用)
enum OutTypes
{
OUT_STDOUT = 0x0001, // stdout <stdio.h>
OUT_STDERR = 0x0002, // stderr <stdio.h>OUT_COUT = 0x0004, // cout <iostream.h>
OUT_CERR = 0x0008, // cerr <iostream.h>
OUT_CLOG = 0x0010, // clog <iostream.h>OUT_OUTPUT_HANDLE = 0x0020, // STD_OUTPUT_HANDLE <winbase.h>
OUT_ERROR_HANDLE = 0x0040, // STD_ERROR_HANDLE <winbase.h>
};// 重定向的目标,用于第二个参数(不可组合使用,一次只能使用一个)
enum RedirectTypes
{
REDIR_TO_NUL , // 重定向到空,什么都不显示
REDIR_TO_CON , // 重定向回到屏幕
REDIR_TO_PRN , // 重定向到打印机(本人没有测试过)
REDIR_TO_FILE , // 重定向到文件,第三个参数指定文件名
REDIR_TO_CALLBACK, // 重定向到回调函数,第三个参数指定回调函数
};// 回调函数形式
typedef VOID (*LPREDIRECT_CALLBACK)(LPCSTR, INT nDataSize, DWORD);// 两种调用格式,到文件或者到回调。第四个参数指定是否 Append 或附加信息 DWORD
// 如果是其他的,第三个参数可省。
BOOL RedirectStdout(INT, RedirectTypes, LPCSTR lpszFileName, BOOL);
BOOL RedirectStdout(INT, RedirectTypes, LPREDIRECT_CALLBACK, DWORD);
3. 使用方法
3.1 头文件
本次提供下载的包中,包含 2 个头文件:"stdredir.h" 和 "stdredirdll.h"。使用第一个头文件将静态连接 "STDRedirStatic.lib",使用第二个头文件动态连接 "STDRedirDll.dll"。
使用时只能包含其中一个头文件,不能将两个同时包含。
3.2 项目设置
本次提供的静态和动态库,均使用 "Multithreaded DLL",DEBUG 版使用 "Debug Multithreaded DLL"。当在控制台运行时需要注意添加 MFC 支持。
4. 下载
[out_redir.zip] - 25kb
5. 举例
5.1 使用下列步骤创建:
- 创建一个 "Dialog based" 项目。
- 在 Dialog 类中,添加静态方法:
static VOID PrintfCallback(LPCSTR szData, INT nDataSize, DWORD dwData);
- 在 Dialog 中,添加一个 CEdit 框和一个按钮。
- 在 OnInitDialog() 中,添加重定向代码:
RedirectStdout(OUT_STDOUT, REDIR_TO_CALLBACK, PrintfCallback, (DWORD)this);
- 在按钮的事件中添加 printf 操作:
printf("test\n");
- 在回调函数中,对 printf 的内容在 CEdit 中显示:
CTDlgTestDlg * pDlg = (CTDlgTestDlg*)dwData;pDlg->m_edtShow.SetSel(
pDlg->m_edtShow.GetWindowTextLength(),
pDlg->m_edtShow.GetWindowTextLength()
);
pDlg->m_edtShow.ReplaceSel(szData);
5.2 示例下载:
[example.zip] - 15kb(需要前面的 out_redir.zip 才能编译连接)
5.3 示例截图

(代码截图)

(运行时截图)
【转载】标准输入输出重定向(Visual C++)的更多相关文章
- C/C++ 标准输入输出重定向
转载自:http://www.cnblogs.com/hjslovewcl/archive/2011/01/10/2314356.html 这个对经常在OJ上做题的童鞋们很有用.OJ基本都是用标准输入 ...
- linux 标准输入输出 重定向
背景: 屏幕打印不一定都是从标准输出来的,也包括标准错误输出流stderr中的信息 文件描述符定义(系统定义了12个) 0 标准输入 1 标准输出 2 标准错误 0 默认键盘输入 1,2默认从屏幕 ...
- linux标准输入输出重定向
command > filename 把标准输出重定向到一个文件,如果文件不存在则新建,如果存在则覆盖其内容.command >> filename 把标准输出重定向到一个文件中,如 ...
- 015 Linux 标准输入输出、重定向、管道和后台启动进程命令
目录 1 三种标准输入输出 2 什么是重定向?如何重定向? (1)什么是重定向? (2)如何重定向? 3 管道符以及和它容易混淆的一些符号使用 (1)管道符 | (2)&和&& ...
- linux标准输入输出与重定向
原文:http://blog.sina.com.cn/s/blog_8333cf8f0100vzzl.html##1 1. 标准输入输出和错误 linux下使用标准输入文件stdin和标准输出文 ...
- 从使用os.system)在python命令(重定向标准输入输出
从使用os.system)在python命令(重定向标准输入输出 python 标准输出stdout stdio os.system通常我可以通过改变sys.stdout的值在python更改标准输出 ...
- Linux Shell系列教程之(十六) Shell输入输出重定向
本文是Linux Shell系列教程的第(十六)篇,更多Linux Shell教程请看:Linux Shell系列教程 Shell中的输出和输入的重定向是在使用中经常用到的一个功能,非常实用,今天就为 ...
- 全面理解Linux输入输出重定向
全面理解Linux输入输出重定向 本教程通过视频方式讲解shell操作,理解感念,教程通俗易懂,比起看一大堆文档要舒服的多.本次教程主要讲解 Linux Shell 中支持输入输出重定向,用符号&l ...
- Python第十天 print >> f,和fd.write()的区别 stdout的buffer 标准输入 标准输出 从控制台重定向到文件 标准错误 重定向 输出流和输入流 捕获sys.exit()调用 optparse argparse
Python第十天 print >> f,和fd.write()的区别 stdout的buffer 标准输入 标准输出 从控制台重定向到文件 标准错误 重定向 输出流和 ...
随机推荐
- 【crunch bang】 增加“菜单项”
[右键菜单]->[Settings]->[Openbox]->[GUI Menu Editor] 挑选合适的位置,增加[菜单项],编辑内容.
- 小心C# 5.0 中的await and async模式造成的死锁
平时在使用C# 5.0中的await and async关键字的时候总是没注意,直到今天在调试一个ASP.NET项目时,发现在调用一个声明为async的方法后,程序老是莫名其妙的被卡住,就算声明为as ...
- Java Persistence API(转)
定义 Java Persistence API JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中.[编辑本段]起源 Sun引入新的JPA ORM规范 ...
- Using Controls in a Form Design [AX 2012]
Using Controls in a Form Design [AX 2012] This topic has not yet been rated - Rate this topic Update ...
- C# Driver LINQ Tutorial
1.介绍 该教程涵盖了1.8版本的C#驱动中的LINQ查询.你可能已经阅读最新的C# Driver Tutorial. 2.快速开始 首先,给程序添加下面的using声明 using MongoDB. ...
- plsql日期乱码
乱码状况如截图: 控制面板\所有控制面板项\系统\高级系统设置\环境变量, 设置系统变量,变量名:NLS_LANG,变量值:Simplified Chinese_China.AL32UTF8改为SIM ...
- C#:DataTable内容转换为String(XML)
//DataTable转String方法 public static String DataTable2String(DataTable dt) { string strXML = "< ...
- Greenplum迁移到配置不同的GP系统
要使用gp_restore或gpdbrestore并行恢复操作,恢复的系统必须与备份的系统具有相同的配置(相同数量的Instance).如果想要恢复数据库对象和数据到配置不同的系统(比如系统扩展了更多 ...
- JAVA 值传递
Java里方法的参数传递方式只有一种:值传递 值传递:当系统开始执行方法时,系统为形参执行初始化,就是把实参变量的值赋给方法的形参变量,方法的操作的并不是实际的实参变量 引用型变量:系统复制的是变量, ...
- Android本机号码及Sim卡状态的获取
SIM卡存储的数据可分为四类:第一类是固定存放的数据.这类数据在移动电话机被出售之前由SIM卡中心写入,包括国际移动用户识别号(IMSI).鉴权密钥(KI).鉴权和加密算法等等.第二类是暂时存放的有关 ...