当前位置:首页 > c++ > 正文内容

c++获取控制台程序的输出(控制台输出重定向)

xuwenyan1年前 (2022-02-11)c++1167

方法1:

利用windows命令>x.txt把控制台内容重定向写入x.txt中,然后通过std::ifstream读取x.txt中的内容以达到获取控制台输出的目的。这个方法过程比较曲折,不可控因素太多,所以不推荐,贴出来仅供参考

代码如下

#include <iostream>
#include<fstream>

int main() {
  // 先清空文件,防止输出内容与上次内容叠加
  std::ofstream ofile("1.txt");
  if (ofile.is_open()) {
    ofile.clear();
    ofile.close();
  }

  system("Ping.exe 192.168.75.1 >>1.txt");

  std::ifstream ifile("1.txt");
  if (ifile.is_open()) {
    std::streampos pos = ifile.tellg();
    ifile.seekg(0, std::ios::end);
    int len = (int)ifile.tellg();
    ifile.seekg(pos);

    char* buffer = new char[len + 1]{ 0 };
    ifile.read(buffer, len);
    std::cout << buffer << std::endl;

    ifile.close();
  }

  getchar();

  return 0;
}

结果展示:



方法2:

利用STARTUPINFO结构中的hStdError和hStdOutput对象,把控制台的输出重写向到我们自己创建的管道中,然后通过管道对象,即可顺利获取控制台的输出,这个方法是推荐使用的。

代码如下:

#include <iostream>
#include <windows.h>

int main() {
  HANDLE hRead, hWrite;    //管道的读写句柄
  SECURITY_ATTRIBUTES sa; //管道安全属性相关结构体

  sa.nLength = sizeof(SECURITY_ATTRIBUTES); //结构体长度赋值
  sa.lpSecurityDescriptor = NULL;           //NULL管道默认安全描述符,管道的安全属性将继承与父程序
  sa.bInheritHandle = TRUE;                 //一个布尔值,指定在创建新进程时是否继承返回的句柄。如果此成员为TRUE,则新进程将继承该句柄。

  if (!::CreatePipe(&hRead, &hWrite, &sa, 0)) {  //尝试创建管道,失败则弹出提示并退出
    ::MessageBox(0, L"Error on CreatePipe()", 0,0);
    return 1;
  }

  STARTUPINFO si;         //启动信息结构体
  PROCESS_INFORMATION pi; //进程信息结构体
  si.cb = sizeof(STARTUPINFO);  //初始化启动信息结构体大小
  ::GetStartupInfo(&si);        //获取父进程的启动信息,利用这个函数我们可以只需要修改较少的参数值
  si.hStdError = hWrite;        //重定向错误信息输出到管道
  si.hStdOutput = hWrite;       //重定向标准输出新信息到管道
  si.wShowWindow = SW_HIDE;     //设定子进程窗体是否隐藏
  si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; //wShowWindow成员将包含其他信息;hStdInput,hStdOutput和hStdError成员包含其他信息。
  if (!::CreateProcess(
    L"C:\Windows\System32\Ping.exe",
    (LPWSTR)L"-t 192.168.75.1",
    NULL, NULL,
    TRUE,                   //新进程继承父进程相关权限
    NULL, NULL, NULL,
    &si,
    &pi)
    ) {
    ::MessageBox(0, L"Error on CreateProcess()", 0, 0);
    return 1;
  }

  ::CloseHandle(pi.hThread);
  ::CloseHandle(pi.hProcess);
  ::CloseHandle(hWrite);    //关闭管道写入句柄

  std::string result;
  char buffer[1025] = { 0 };
  DWORD bytesRead;
  while (true) {   //读取管道内的数据
    memset(buffer, 0, 1025);
    if (::ReadFile(hRead, buffer, 1024, &bytesRead, NULL) == NULL) break;
    result += buffer;
    ::Sleep(100);
  }

  std::cout << result << std::endl;

  getchar();
  return 0;
}

结果展示:



    文章作者:xuwenyan
    版权声明:本文为本站原创文章,转载请注明出处,非常感谢,如版权漏申明或您觉得任何有异议的地方欢迎与本站取得联系。

    扫描二维码推送至手机访问。

    版权声明:本文由艺文笔记发布,如需转载请注明出处。

    本文链接:https://www.xuwenyan.com/archives/2425

    分享给朋友:

    “c++获取控制台程序的输出(控制台输出重定向)” 的相关文章

    C++如何实现挂起进程、恢复进程

    C++如何实现挂起进程、恢复进程

    1:枚举进程的所有线程,使用SuspendThread函数挂起每一个线程,需要恢复时使用ResumeThread函数恢复。因为挂起和恢复的顺序是不可预知的,所以可能会导致一些多线程程序崩溃,单线程程序可能不受影响。void SuspendProcess(DWORD process...

    Visual Studio编译7z源代码

    Visual Studio编译7z源代码

    源代码下载打开地址https://www.7-zip.org/download.html,选择源码下载,可以选择自己需要的版本下载7z.dll编译1:解压源代码包,打开vs解决方案,CPP7zipBundlesFormat7zFFormat7z.dsw,vs会提示升级,不用管,选择升级。2:修改7z...

    7z的简介和使用

    7z的简介和使用

    7z是一个支持多种压缩格式的开源项目,由Igor Pavlov开发,源码下载位置:https://www.7-zip.org/download.html源码结构项目源码目录结构是如下图:Asm包含主要算法实现的汇编代码,直接使用汇编的好处是可以提高运行效率,当然这对跨平台的支持不是很好。C主要是算法...

    C++如何实现窗口全屏显示

    C++如何实现窗口全屏显示

    窗口全屏,直接上代码:void FullScreen(HWND hwnd) {   //去掉所有边框,解决虚拟机win10任务栏显示问题   DWORD style = ::GetWindowLo...

    C++如何获取控制台程序的输出内容?

    C++如何获取控制台程序的输出内容?

    很多工具程序(如ffmpeg)的进度显示往往都是以控制台字符显示的方法,我们可能需要调用这种控制台工具去完成工作,但同时又希望以友好的ui界面去显示当前的工作状态(如进度)。此时我们能想到的就是运行控制台程序,然后以某种方式去获取到控制台程序的输出,然后转换到我们的ui界面上去显示。 有多种...

    使用GDI、MFC_GDI、GDI+绘制数组RGBA序列

    使用GDI、MFC_GDI、GDI+绘制数组RGBA序列

    学习ffmpeg时遇到一个问题,ffmpeg解码出RGB颜色后怎么绘制到屏幕上,于是将GDI、MFC_GDI、GDI+等方式都记录一下 1:注意按windows的要求,R、G、B、A顺序要调整为B、G、R、A 。 2:GDI不支持透明通道A,透明通道A的值读进去以后没有作用。想要支持透...