首页 > 编程语言 >C++程序获取python脚本控制台输出的一种方法

C++程序获取python脚本控制台输出的一种方法

时间:2023-07-30 10:05:52浏览次数:47  
标签:输出 读取 python popen C++ 进程 控制台 include


作者:朱金灿

为什么大多数人学不会人工智能编程?>>>

  最近要使用C++程序调用python脚本,调用方法是通过启动python进程来调用,其中遇到的一个问题是在C++程序中需要获取python脚本的控制台输出信息。经过摸索使用_popen函数实现了。下面用python脚本和C++调用示例程序来说明。python示例程序如下:

import os
import sys

if __name__ == "__main__":
    print("program start!")
    print("program end!")

C++示例程序如下:

#include <iostream>
#include <cstdlib>
#include <stdlib.h>
#include <fstream>
#include <string>
#include <map>
#include <thread>
#include <future>
#include <sstream>
//获取python脚本的控制台输出字符串
std::string GetPythonConsoleOutput()
{
	std::stringstream ss;
	auto py_prog = std::async(std::launch::async, [&ss]() 
	{
		//python命令行
		std::string cmd = "python D:\\MyProject\\PythonCodeLib\\UtilityTest\\ConsoleOutput.py";

#ifdef _WINDOWS

		FILE* in = _popen(cmd.c_str(), "r");
		char buf[1024];
		while (fgets(buf, sizeof(buf), in) != NULL)
		{
			ss << buf;
		}
		_pclose(in);

#else

		FILE* in = popen(cmd.c_str(), "r");
		char buf[1024];
		while (fgets(buf, sizeof(buf), in) != NULL) 
		{
			ss << buf;
		}
		pclose(in);

#endif
	});

	py_prog.wait();
	return ss.str();
}

int main()
{
	std::string strRet = GetPythonConsoleOutput();
	std::cout << strRet << std::endl;
	getchar();
    return 0;
}

效果图如下:

C++程序获取python脚本控制台输出的一种方法_#include


  需要注意的是C++程序用到了C++11中的std::async组件,同时程序是支持跨平台的,创建管道和启动子进程的函数在windows上是_popen,在linux下是popen。还有在Windows平台上使用_popen启动子进程后,如果无法获取到子进程向控制台的输出字符串,主要有以下几个原因:

1)没有正确设置_popen的读写模式

_popen的第二个参数需要设置为"r"才可以读取子进程的输出。如果设置为"w",则只能向子进程输入。

2)未正确读取输出缓冲区

_popen打开进程后,需要通过fgets/fread等函数读取文件句柄,才能获取输出。否则输出可能被缓冲在管道中。

3)子进程未输出到标准输出

子进程内如果没有用cout/printf向标准输出打印,是无法通过_popen读取的。需要子进程也输出到stdout。

4)读取时机错误

如果在子进程退出前就读取_popen句柄,则可能读取不完整。需要在子进程退出后再读取。

5)未正确关闭句柄

需要调用_pclose来关闭_popen的文件句柄,释放资源。

6)重定向导致无法捕获标准输出

子进程内如果重定向了标准输出到文件等其他地方,也无法通过_popen读取。

  综上,使用_popen获取子进程输出需要注意读写模式、缓冲读取、标准输出重定向等问题。需要双方配合才能正确传递输出。


标签:输出,读取,python,popen,C++,进程,控制台,include
From: https://blog.51cto.com/u_15456319/6898589

相关文章

  • 【Python】使用 pyecharts 模块绘制动态时间线柱状图 ① ( 列表排序 | 使用 sorted 函
    文章目录一、列表排序1、使用sorted函数对容器进行排序2、使用list.sort函数对列表进行排序3、使用list.sort函数对列表进行排序-设置排序函数4、使用list.sort函数对列表进行排序-设置lambda匿名排序函数pyecharts画廊网站:https://gallery.pyecharts.org/#/......
  • 使用Python统计下桌面某个文件夹下(含多层子文件夹)具体文件的数量(方法三)
    大家好,我是皮皮。一、前言前几天在Python最强王者群【东哥】问了一个Python自动化办公的问题,一起来看看吧。这个是他自己在实际工作中遇到的需求,正好遇到了这个问题,想着用Python来实现下。二、实现过程上一篇文章中已经分享了一个方法,这一篇文章继续分享另外一个方法,由【巭孬......
  • VS选择Visual C++中的控制台项目和空项目、Windows桌面应用程序三者之间有什么区别?
    在VisualStudio中创建C/C++项目时,可以选择控制台项目、空项目和Windows桌面应用程序,它们有以下区别:控制台项目(ConsoleApplication):这种项目类型适用于命令行应用程序的开发。它提供一个命令行界面,可以在控制台中进行输入和输出操作,通常用于简单的控制台程序,如计算器、文件......
  • C++运算符重载
    1.概念赋予运算符更多的功能。2.内容赋值运算符+-*/%运算符自增自减运算符输出流运算符的重载<<输入流运算符的重载>>函数调用运算符()下标运算符[]成员访问运算符->,*3.赋值运算符这个一般是用已存在的对象赋值给另一个已存在的对象。//如存在Comp......
  • 使用python基于boto3和tkintrer模块-编写一个AWS-EC2的管理器界面
    当我们管理自己AWS账号下的EC2资源时,一般都是登录到Console界面进行管理笔者自己的AWS经常是用于做一些实验时,才会去创建EC2,部署一些环境等,为了不用登录Console操作于是使用python,tkinter模块写了一个GUI的管理工具,先看一下整体界面如下:这个小工具,有创建EC2,查询EC2,删除指......
  • C++中fork函数的使用及原理
    C++中fork函数的使用及原理,在C++中,fork函数用于创建一个新的进程称为子进程,该进程与原始进程几乎完全相同。fork函数的基本概况fork()函数调用成功之后,会有两个返回值。当前进程,也就是父进程返回子进程的pid,子进程返回0。如果函数调用错误,返回为-1。#include<stdio.h>#include......
  • C++中的exec()函数
    exec()函数在C++中是一个进程控制函数,用于创建新进程执行其他程序或命令行指令。exec()函数可以替换当前进程的代码和数据,创建新的进程运行其他程序。exec()函数有多个版本,例如execl、execv、execle、execve等,根据不同的参数类型和个数来使用。前言fork函数之后,如果想要把子进程换......
  • C++实现简单的ls命令以及原理
    C++实现简单的ls命令及其原理,C++实现ls命令可通过调用系统函数实现读取目录中的文件名和属性,再通过标准输出进行显示。对控制参数的处理一共有7个可选参数,分别是-a、-l、-R、-t、-r、-i、-s,这些参数可以相互自由组合,因此可以设计一种机制,就是直接把它们全部用循环一次性做或运算,......
  • C++实现工资管理中的随机教师信息生成功能
    使用C++实现工资管理中的随机教师信息生成功能,想要做一个教师工资管理系统,就必须得准备好数据,但是这些数据如果用手一行一行地敲,那么工作量是非常大的,因此,我就产生了用C语言实现直接生成大量的教师基本信息的想法,需要的朋友可以参考下。教师的基本信息typedefstructteacher{......
  • 如何在 Python 中计算列表中的唯一值?
    Python提供了各种方法来操作列表,这是最常用的数据结构之一。使用列表时的一项常见任务是计算其中唯一值的出现次数,这在数据分析、处理和筛选任务中通常是必需的。在本文中,我们将探讨四种不同的方法来计算Python列表中的唯一值。在本文中,我们将介绍如何使用集合模块中的集合、字......