Как перенаправить вывод системного вызова внутренней части программа в C/C++?

Я пишу программу в C++, которые делают некоторый специальный режим для всех файлов в текущем каталоге на Linux ОС.

Таким образом, я думал об использовании системных вызовов такой как system("ls") получить список всех файлов.

но как сохранить его затем в моей программе? (как перенаправить вывод ls к скажем, строке, которую я объявил в программе),

Спасибо

5
задан Debugger 16 April 2010 в 18:41
поделиться

6 ответов

Я предлагаю вам не обращаться к 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;
}
7
ответ дан 18 December 2019 в 05:24
поделиться

Простой способ сделать это - использовать итератор каталогов 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
ответ дан 18 December 2019 в 05:24
поделиться

Я не думаю, что вы можете использовать систему для чтения вывода.

Попробуйте использовать popen .

   #include <stdio.h>

   FILE *popen(const char *command, const char *type);

   int pclose(FILE *stream);

Но вы, вероятно, не захотите делать это для ls . Две причины:

  • Если вы хотите получить список каталогов, используйте api файловой системы напрямую ( readdir ), вместо использования команд оболочки и его синтаксического анализа.
  • Кто-то указал мне на сообщение в блоге , в котором недавно объяснялось, почему синтаксический анализ вывода ls - плохая идея.
10
ответ дан 18 December 2019 в 05:24
поделиться

Вы используете UNIX или Windows? В UNIX вы должны создать дочерний процесс с помощью вызова fork (), а затем создать несколько каналов и назначить STDOUT дочернего процесса на STDIN родительского процесса. В Windows обязательно должно быть что-то подобное в Win32 API.

1
ответ дан 18 December 2019 в 05:24
поделиться

Я вижу 3 варианта:

  1. Выполните систему ("ls> tempfile") , а затем прочтите вывод ls из tempfile
  2. Откройте канал с помощью pipe () , затем используйте fork () для создания нового процесса. В дочернем процессе закройте файловый дескриптор 2 и замените его записывающим концом канала, вызвав dup () . Затем вызовите exec ("ls", ...) в дочернем процессе. Наконец, прочтите вывод ls из конвейера в родительском процессе
  3. . Не используйте ls для перечисления файлов в текущем каталоге. В вашей программе есть функции для этого, например opendir (), readdir (), closedir .

Я настоятельно рекомендую вариант 3.

0
ответ дан 18 December 2019 в 05:24
поделиться

Либо используйте подходящие вызовы c для чтения файлов в каталоге, либо обобщите свою программу так, чтобы она принимала список файлов в качестве входных данных и передавала этот список из ls по конвейеру в вашу программу

> ls | yoursoftware
0
ответ дан 18 December 2019 в 05:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: