gpt4 book ai didi

c++ - 从 popen 到 ifstream.open 的文件输出列表

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:56:07 24 4
gpt4 key购买 nike

基本上我需要打开并读取从另一个命令获得的文件列表。对于 popen 的每一行输出 使用 ifstream.open 打开一个文件

它可以编译,如果我直接输入文件名,它可以正常工作,但在使用 popen 输出时它什么都不做。我见过这样的问题,但没有这种提供文件名的特殊方式。

代码如下:

#include <iostream>
#include <sqlite3.h>
#include <stdio.h>
#include <fstream>

using namespace std;


int main () {

ifstream singlefile;
FILE *filelist;
char filename[512];
string progline;

if(!(filelist = popen("find `pwd` -name \"*.js\"", "r"))){
return 1;
}

while( fgets(filename, sizeof(filename), filelist)!=NULL)
{
cout << filename;
singlefile.open(filename, ifstream::in);
while ( singlefile.good() )
{
getline (singlefile,progline);
cout << progline << endl;
}

singlefile.close();
}

pclose(filelist);

return 0;

}

下一步不是在循环中打开每个文件,而是存储文件列表,然后打开每个文件。

谢谢

最佳答案

fgets 保留尾随换行符,导致文件名不存在。此外,流状态仅在读取后更新。如果我用以下代码替换 while 主体,它对我有用:

  cout << filename;
size_t len = strlen(filename);
// chop off trailing newline
if (len > 1 && filename[len - 1] == '\n') filename[len - 1] = 0;
singlefile.open(filename, ifstream::in);
while ( getline(singlefile, progline) )
{
cout << progline << endl;
}

singlefile.close();

如果您真的想遍历文件列表,我会使用 Boost.Filesystem ,它有一个很好的 C++ 接口(interface),适用于所有文件名(甚至适用于那些有换行符的文件名),并且与平台无关。

如果这实际上只是一个示例,并且您的实际命令不是find,那么仍有一些简化的空间。这是一个使用 Boost.Iostreams 的建议摆脱大部分 C 函数调用(从进程的标准输出中读取设备源会很棒,但 Boost.Iostreams 缺乏):

#include <cstdio>
#include <iostream>
#include <fstream>
#include <stdexcept>
#include <string>

#include <stdio.h>

#include <boost/noncopyable.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>

using namespace std;
namespace io = boost::iostreams;

class Popen: private boost::noncopyable {
public:
explicit Popen(const char* command):
m_stream(popen(command, "r")) {
if (!m_stream) throw runtime_error("popen failed");
}

~Popen() {
pclose(m_stream);
}

FILE* stream() const {
return m_stream;
}

private:
FILE* m_stream;
};


int main() {
Popen pipe_wrapper("find `pwd` -name \"*.cpp\"");
io::file_descriptor_source pipe_device(fileno(pipe_wrapper.stream()), io::never_close_handle);
io::stream<io::file_descriptor_source> pipe_stream(pipe_device, 0x1000, 0x1000);
string filename;
while (getline(pipe_stream, filename)) {
cout << filename << endl;
ifstream file_stream(filename.c_str(), ifstream::in);
string progline;
while (getline(file_stream, progline)) {
cout << progline << endl;
}
}
}

关于c++ - 从 popen 到 ifstream.open 的文件输出列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9591963/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com