原文:标准输入输出重定向(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 个:

  1. 哪些输出要被重定向。比如:指定 (stderr | cout) ,那么其他的输出仍然输出到屏幕。
  2. 重定向到哪里。比如:重定向到文件,还是到屏幕,还是到回调函数。
  3. 文件名。如果是重定向到文件,则需要指定文件名。
  4. 回调函数。如果是重定向要回调函数,则需要指定回调函数。

接口头文件:

// 可能的输出,用在第一个参数(可组合使用)
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 使用下列步骤创建:
  1. 创建一个 "Dialog based" 项目。
     
  2. 在 Dialog 类中,添加静态方法:
    static VOID PrintfCallback(LPCSTR szData, INT nDataSize, DWORD dwData);
     
  3. 在 Dialog 中,添加一个 CEdit 框和一个按钮。
     
  4. 在 OnInitDialog() 中,添加重定向代码:
    RedirectStdout(OUT_STDOUT, REDIR_TO_CALLBACK, PrintfCallback, (DWORD)this);
     
  5. 在按钮的事件中添加 printf 操作:
    printf("test\n");
     
  6. 在回调函数中,对 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++)的更多相关文章

  1. C/C++ 标准输入输出重定向

    转载自:http://www.cnblogs.com/hjslovewcl/archive/2011/01/10/2314356.html 这个对经常在OJ上做题的童鞋们很有用.OJ基本都是用标准输入 ...

  2. linux 标准输入输出 重定向

    背景: 屏幕打印不一定都是从标准输出来的,也包括标准错误输出流stderr中的信息 文件描述符定义(系统定义了12个) 0 标准输入 1 标准输出 2 标准错误   0 默认键盘输入 1,2默认从屏幕 ...

  3. linux标准输入输出重定向

    command > filename 把标准输出重定向到一个文件,如果文件不存在则新建,如果存在则覆盖其内容.command >> filename 把标准输出重定向到一个文件中,如 ...

  4. 015 Linux 标准输入输出、重定向、管道和后台启动进程命令

    目录 1 三种标准输入输出 2 什么是重定向?如何重定向? (1)什么是重定向? (2)如何重定向? 3 管道符以及和它容易混淆的一些符号使用 (1)管道符 | (2)&和&& ...

  5. linux标准输入输出与重定向

    原文:http://blog.sina.com.cn/s/blog_8333cf8f0100vzzl.html##1 1. 标准输入输出和错误    linux下使用标准输入文件stdin和标准输出文 ...

  6. 从使用os.system)在python命令(重定向标准输入输出

    从使用os.system)在python命令(重定向标准输入输出 python 标准输出stdout stdio os.system通常我可以通过改变sys.stdout的值在python更改标准输出 ...

  7. Linux Shell系列教程之(十六) Shell输入输出重定向

    本文是Linux Shell系列教程的第(十六)篇,更多Linux Shell教程请看:Linux Shell系列教程 Shell中的输出和输入的重定向是在使用中经常用到的一个功能,非常实用,今天就为 ...

  8. 全面理解Linux输入输出重定向

    全面理解Linux输入输出重定向 本教程通过视频方式讲解shell操作,理解感念,教程通俗易懂,比起看一大堆文档要舒服的多.本次教程主要讲解  Linux Shell 中支持输入输出重定向,用符号&l ...

  9. Python第十天 print >> f,和fd.write()的区别 stdout的buffer 标准输入 标准输出 从控制台重定向到文件 标准错误 重定向 输出流和输入流 捕获sys.exit()调用 optparse argparse

    Python第十天   print >> f,和fd.write()的区别    stdout的buffer  标准输入 标准输出  从控制台重定向到文件  标准错误   重定向 输出流和 ...

随机推荐

  1. ios学习笔记(二)第一个应用程序--Hello World

    原文地址:http://blog.csdn.net/shangyuan21/article/details/18416537 上一篇文章,Windows7上使用VMWare搭建iPhone开发环境介绍 ...

  2. Java笔试题解答和部分面试题

    面试类  银行类的问题 问题一:在多线程环境中使用HashMap会有什么问题?在什么情况下使用get()方法会产生无限循环? HashMap本身没有什么问题,有没有问题取决于你是如何使用它的.比如,你 ...

  3. Left Join 与Right Join 与 Inner Join 与 Full Join的区别

    首先看看Left Join 与Right Join 与 Inner Join 与 Full Join对表进行操作后得到的结果. 在数据库中新建两张表,并插入要测试的数据. 新建表: USE [Test ...

  4. sql server 数据库模型 备份 恢复 总结 备份脚本

    事务日志是可以基于时间点恢复的,必须在full或bulk_logged模式下 Alter database [DBName] set recover bulk_logged , then the fo ...

  5. 161124、Java 异常处理的误区和经验总结

    本文着重介绍了 Java 异常选择和使用中的一些误区,希望各位读者能够熟练掌握异常处理的一些注意点和原则,注意总结和归纳.只有处理好了异常,才能提升开发人员的基本素养,提高系统的健壮性,提升用户体验, ...

  6. MyEclipse下搭建maven项目

    由于maven在构建项目方面确实比较出色,现今绝大多数人构建项目都采用maven,而且绝大多数人都采用eclipse作为开发环境,今天我用myeclipse搭建了一个demo,虽然基本上不会采用mye ...

  7. javascript || and &&

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. 探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法

    前言相信这样一个问题,大家都不会陌生,“有什么的方法可以使Android的程序APK不用安装,而能够直接启动”.发现最后的结局都是不能实现这个美好的愿望,而腾讯Android手机游戏平台却又能实现这个 ...

  9. Shell 字符串比较

    转自网络 Shell字符串比较 收藏 Shell 中整数比较方法及字符串的比较方法,如等于,不等于,大于,大于等于,小于,等等. 二元比较操作符,比较变量或者比较数字.注意数字与字符串的区别. --- ...

  10. linux正则表达式使用

    首先介绍下正则表达式,它是由一串字符和元字符构成的字符串,简称RE(Regular Expression),它的主要功能是文本查询和字符串操作,它可以匹配一个文本的字符和字符集,达到数据过滤的效果. ...