我正在用C ++编写一个程序,它对Linux OS上当前目录中的所有文件进行了一些特殊处理。
所以我考虑使用system("ls")
之类的系统调用来获取所有文件的列表。
但是如何将它存储在我的程序中? (如何重定向ls的输出,让我们说一个我在程序中声明的字符串)
由于
答案 0 :(得分:14)
共识似乎不是使用“ls”。但是,对于有兴趣执行此功能的任何人:
/**
* Execute a command and get the result.
*
* @param cmd - The system command to run.
* @return The string command line output of the command.
*/
string GetStdoutFromCommand(string cmd) {
string data;
FILE * stream;
const int max_buffer = 256;
char buffer[max_buffer];
cmd.append(" 2>&1"); // Do we want STDERR?
stream = popen(cmd.c_str(), "r");
if (stream) {
while (!feof(stream))
if (fgets(buffer, max_buffer, stream) != NULL) data.append(buffer);
pclose(stream);
}
return data;
}
答案 1 :(得分:10)
我认为您不能使用系统来读取输出。
尝试使用popen
。
#include <stdio.h>
FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);
但是,您可能不希望为ls
执行此操作。有两个原因:
readdir
),而不是使用shell命令并解析它。ls
输出是一个坏主意。答案 2 :(得分:7)
我建议您不要呼叫ls
- 正确完成工作,使用opendir/readdir/closedir
直接读取目录。
代码示例,打印目录条目:
// $ gcc *.c && ./a.out
#include <stdlib.h> // NULL
#include <stdio.h>
#include <dirent.h>
int main(int argc, char* argv[]) {
const char* path = argc <= 1 ? "." : argv[1];
DIR* d = opendir(path);
if (d == NULL) return EXIT_FAILURE;
for(struct dirent *de = NULL; (de = readdir(d)) != NULL; )
printf("%s/%s\n", path, de->d_name);
closedir(d);
return 0;
}
答案 3 :(得分:4)
一种简单的方法是使用boost filesystem目录迭代器。或者像其他人建议的那样使用opendir / readdir / closedir。你前进的方式没有真正的好处。
代码示例,指定目录中常规文件的打印大小:
// $ g++ listdir.cc -o listdir -lboost_filesystem && ./listdir
#include <iostream>
#include <boost/filesystem.hpp>
int main(int argc, char* argv[]) {
using std::cout;
using namespace boost::filesystem;
std::string path(argc <= 1 ? "." : argv[1]);
if (is_directory(path)) {
for (directory_iterator itr(path); itr!=directory_iterator(); ++itr) {
cout << itr->path().filename() << ' '; // display filename only
if (is_regular_file(itr->status())) // display size for regular files
cout << " [" << file_size(itr->path()) << ']';
cout << '\n';
}
}
else cout << (exists(path) ? "Found: " : "Not found: ") << path << '\n';
}
答案 4 :(得分:1)
选项4.使用popen();
答案 5 :(得分:0)
您是在UNIX还是Windows?在UNIX上,您将使用fork()调用创建子进程,然后创建一些管道并将子进程的STDOUT分配给父进程的STDIN。在Windows上,Win32 API中必然存在类似的东西。
答案 6 :(得分:0)
我看到3个选项:
system("ls > tempfile")
然后从tempfile ls
的输出
pipe()
打开管道,然后使用fork()
生成新进程。在子进程中关闭文件描述符2并通过调用dup()
替换管道的结尾。接下来,在子进程中调用exec("ls",...)
。最后从父进程ls
的输出
ls
枚举当前目录中的文件。在您的计划中有一些功能,即opendir(),readdir(),closedir
。我强烈推荐选项3。
答案 7 :(得分:0)
使用适当的c调用来读取目录中的文件,或者对程序进行概括,以便将文件列表作为输入并将该列表从ls piped传递到程序
> ls | yoursoftware
答案 8 :(得分:0)
我认为pajton的#2是这个问题最合适的答案。
可能“ls”不是您想要使用它的命令的最佳示例,因为可以使用其他本机C库函数来执行此操作,但是还有其他程序可以生成您可能需要的输出无需执行写入/读取文件即可立即处理。
#1在UNIX / Linux类型系统上也很好,它实现了一个高效的RAM文件系统,可用于读/写系统全局数据。几乎在所有系统上,它都是一种非常好的“快速”“脏”方式来完成工作。
同样,大多数响应提供了使用本机C库获取目录内容的更好方法,但是有些实例包括pipe(),fork(),dup(),exec(),system( )和popen()适合与系统进程通信。
答案 9 :(得分:0)
使用fork()/ exec()和pipe()系统调用似乎是Unix上最好的通用方法。这样可以最简单地分离调用程序的标准输出和标准错误流。人们也可以等待产生的过程并收获它,收集它的退出状态。最后,如果需要,可以使用非阻塞I / O从调用的程序的输出/错误中读取。
最大的问题是,要在Windows上实现类似的功能,您可能需要编写几百行代码。我没有找到更好的方法,并且没有在Windows环境中研究过这个问题。