Linux — простой способ вызвать «кошка» из C ++?

Я пишу код на C ++, и мне нужно предварительно выделить массив на основе содержимого файла. Я определенно могу прочитать файл и разобрать строки определенным образом, но должно быть проще найти правильный номер из следующей строки Linux:

cat myfile.txt | grep 'Freqs ---' | sed 's/Freqs ---//g' | wc -w

Каков наилучший способ использовать этот единственный вкладыш в файле из кода C ++?

0

Решение

использование popen от <stdio.h>:

FILE *fp;
char buffer[BUFFER_SIZE];

fp = popen("cat myfile.txt | grep 'Freqs ---' | sed 's/Freqs ---//g' | wc -w", "r");
if (fp != NULL)
{
while (fgets(buffer, BUFFER_SIZE, fp) != NULL)
printf("%s", buffer);
pclose(fp);
}

Возвращаемое значение из popen стандартный поток ввода / вывода, такой же, как fopen, Тем не менее, вы должны использовать pclose вместо fclose закрыть поток.

4

Другие решения

С помощью system() может быть опасным делом (в агрессивной среде).
С помощью popen() не намного лучше.
На самом деле лучше научиться делать подобные вещи прямо в вашей программе:

Это получит размер файла.

#include <stdlib.h>
#include <sys/stat.h>
...
struct stat st;
...
size_t bytes = 0;

if (stat("myfile.txt", &sb) == -1) { /* an error, do something */ }
else bytes = st.st_size;

Однако, чтобы сделать то, что делает ваш лайнер, потребуется прочитать файл:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

size_t  bytes = 0;
char    line[256];
FILE *  fp = fopen("myfile.txt", "r");
char *  p;
char *  freqs;
int     n;

if (fp == NULL) { /* an error, do something */ }
else while (fgets(line, sizeof(line), fp) != NULL) {
for (n = 0, p = line; (p = strstr(p, "Freqs ---")) != NULL; n++) {
p += 9;                                    /* skip past found one */
}
if (n != 0) bytes += strlen(line) - (n * 9);   /* line len less n "Freqs ---" */
}
if (fp) fclose(fp);

Из-за g в вашем sed команда, я предположил Freqs --- может встречаться более одного раза в строке. Если это никогда не произойдет более одного раза, код может быть немного проще.

1

Вы, вероятно, хотите popen() но такие подходы не так уж переносимы.

Вот 21-летний (!!) фрагмент, который я имел в misc/C/ подкаталог:

/* edd 01.11.95 write pipe to "wc" command */

#include <stdlib.h>
#include <stdio.h>

int main() {
FILE *pipe;

pipe = popen("wc", "w");
fprintf(pipe, "w\n");
fprintf(pipe, "wc\n");
pclose(pipe);
return 0;
}

Вы также можете читать из канала (так же, как вы можете из файла), а затем использовать, скажем, fscanf() читать твой ответ.

0

Использовать system функция из стандартной библиотеки («унаследованная» от C). Что-то вроде:

system("cat myfile.txt | grep 'Freqs ---' | sed 's/Freqs ---//g' | wc -w");

Документация по этой функции находится здесь: http://www.cplusplus.com/reference/cstdlib/system/

Чтобы получить результат — вывод из wc, перенаправьте его в файл, а затем откройте файл и strtod его содержание.

0