使用(希望是标准的)C++工具读取文件*
reading a FILE* with (hopefully standard) C++ tools?
我需要从我的程序中读取另一个程序的输出。为此,我可以使用 popen()。这样,我就可以得到一个可以在我的程序中解析的程序输出的 FILE*。如何从我的程序中读取和解析 popen() 返回值的内容?或者,在某个地方是否有更像 C++ 的 popen 版本?
您可以创建一个流缓冲区,执行道德等效popen()
,也可以创建一个流缓冲区包装FILE*
。获得流缓冲区后,您可以将其与std::istream
一起使用,这似乎是您打算做的。从FILE*
读取的简单(未经测试)流缓冲区如下所示:
struct FILEbuf
: std::streambuf {
FILEbuf(FILE* fp): fp_(fp) {}
int underflow() {
if (this->gptr() == this->egptr()) {
int size = fread(this->buffer_, 1, s_size, this->fp_);
if (0 < size) {
this->setg(this->buffer_, this->buffer_, this->buffer_ + size);
}
}
return this->gptr() == this->egptr()
? traits_type::eof()
: traits_type::to_int_type(*gptr());
}
FILE* fp_;
enum { s_size = 1024 };
char buffer_[s_size];
};
我认为我打错了一些东西,但大致这个想法确实有效:只需从FILE*
读取到流缓冲区即可。或者,创建从生成的进程读取流。这需要几个特定于平台的调用来fork()
、exec..()
、pipe()
、close()
、dup2()
(可能这里也忘记了一些东西),但也可以完成。
可以使用像上面这样的流缓冲区,例如,像这样:
int main()
{
FILEbuf sbuf(fopen("pstream.cpp", "r"));
std::istream in(&sbuf);
for (std::string line; std::getline(in, line); ) {
std::cout << line << 'n';
}
}
FILE*
有一个C++包装器,称为stdio_filebuf
(GNU实现)或stdiobuf
。我认为这不是一个标准化的东西,但如果你谷歌搜索stdiobuf
你会发现它在许多平台上都可用。下面是一个如何将其与从 popen
返回的 FILE*
指针一起使用的工作示例,使用 gcc 4.5.0 编译并在 Linux 机器上进行测试:
#include <ext/stdio_filebuf.h>
#include <stdio.h>
#include <fstream>
#include <string>
#include <iostream>
using namespace std;
int main() {
FILE* f = popen("ls", "r");
__gnu_cxx::stdio_filebuf<char> fdbuf(f, std::ios::in);
std::ifstream in;
in.std::ios::rdbuf(&fdbuf);
string s;
in >> s;
cout << s;
pclose(f);
return 0;
}
相关文章:
- 使用外部SDK工具链文件在VisualStudio上生成项目编译错误
- 在clang++预处理器中确定gcc工具链版本
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 参数化自定义CMake工具链
- 如何在QT中的自定义视频小工具t上绘制矩形
- 使用 C++ 和 i2c 工具从虚拟 i2c 写入和读取
- 用于C++的静态二进制检测或二进制重写工具和框架
- 在OSX上使用CMake将Adobe的XMP工具包构建为共享库的最简单方法是什么?
- AWS IoT 开发工具包:通过 TCP 端口 443 使用 MQTT
- 在官方张量流 resnet50 模型上运行 tflite 精度工具
- Q没有管理权限的 exe 无法启动维护工具
- C++合并排序可视化工具
- 为Bazel工具链指定sysroot
- 在自动工具中包含用于不同bin_Programs的不同库
- 如何使用MSVC 2019创建和使用Qt 5.14.0自定义小工具插件
- Eclipse CDT clang 工具链 - 无法从链接器选项中删除 stdlibc++,但可以添加 libc++,E
- 使用不同的工具时,Eccodes 会产生不同的结果
- Clang 工具,用于提取给定 lambda 类型的 lambda 主体
- 构建LLVM 10 C++工具链的问题
- 使用即将推出的C++反射工具打印类型的全名