Используйте вывод cat в другой программе с каналом в C

Я хочу запустить: cat somefile | program > outputText в системе UNIX.

Я просмотрел многие вещи, такие как pipe, использование popen, dup2 и т. д.; Я потерян.

Основной код должен быть:

  • Прочитайте все, что выводит cat, используя program, и сделайте немного волшебства, а затем выведите данные в outputText.

Любые советы, пожалуйста?

P.S. Файлы являются двоичными.

ОБНОВЛЕНИЕ:

Я нашел этот код, который работает с предписанной командой выше... Но он делает то, что мне не нужно.

  1. Как избавиться от sort? Я пытался стереть что-то, но потом получаю ошибки и программа не запускается.
  2. Чтение данных с помощью cat в двоичном виде
  3. Вывод данных на терминал в бинарном виде

Любые советы, пожалуйста?

int main(void)
{
    pid_t p;
    int status;
    int fds[2];
    FILE *writeToChild;
    char word[50];

    if (pipe(fds) == -1)
    {
        perror("Error creating pipes");
        exit(EXIT_FAILURE);
    }

    switch (p = fork())
    {
        case 0: //this is the child process
            close(fds[1]); //close the write end of the pipe
            dup2(fds[0], 0);
            close(fds[0]);
            execl("/usr/bin/sort", "sort", (char *) 0);
            fprintf(stderr, "Failed to exec sort\n");
            exit(EXIT_FAILURE);

        case -1: //failure to fork case
            perror("Could not create child");
            exit(EXIT_FAILURE);

        default: //this is the parent process
            close(fds[0]); //close the read end of the pipe
            writeToChild = fdopen(fds[1], "w");
            break;
    }

    if (writeToChild != 0)
    {
        while (fscanf(stdin, "%49s", word) != EOF)
        {
            //the below isn't being printed.  Why?
            fprintf(writeToChild, "%s end of sentence\n", word);
        }
        fclose(writeToChild);
    }

    wait(&status);

    return 0;
}

person raffaello    schedule 19.09.2014    source источник
comment
Зачем вам использовать cat для передачи в него, когда вы можете просто установить stdin из program на somefile? то есть program < somefile > outputText   -  person FatalError    schedule 19.09.2014
comment
В моей задаче указано, что я должен сделать это так, к сожалению.   -  person raffaello    schedule 19.09.2014
comment
И файл, прочитанный cat, является двоичным, и вывод должен быть двоичным, если это возможно.   -  person raffaello    schedule 19.09.2014
comment
Мне нужно иметь 2 файла? Один файл делает трубопровод? Я заметил, что многие программы вызывают exec(), где они вызывают определенный файл, в моем случае это будет программа? Итак, pipe.c вызовет program.c и каким-то образом возьмет stdout из cat и поместит его в program.c???   -  person raffaello    schedule 19.09.2014
comment
Если вы, как вы говорите, должны (домашнее задание?) запустить программу как cat somefile | program > output, то вы на неверном пути. Выполнение такой команды делает оболочку трубой для вывода из cat во вход program. Это не то же самое, что настроить канал внутри вашей программы. en.wikipedia.org/wiki/Redirection_(computing)#Piping   -  person Henrik    schedule 19.09.2014
comment
Это упражнение по кодированию для клубного конкурса. В любом случае, я должен следовать этому формату сценария. У меня есть некоторые вещи, работающие с кодом, который я опубликовал до сих пор, но все еще не идеально. @ Хенрик, это именно то, что я хочу, чтобы вывести вывод cat в stdin из program!   -  person raffaello    schedule 19.09.2014
comment
А ваша программа такая же как program в команде?   -  person Henrik    schedule 19.09.2014
comment
@ Хенрик, program или назовите это как угодно, предполагается, что textAlteration изменяет ввод stdin, который подается из cat.   -  person raffaello    schedule 19.09.2014
comment
Тогда все, что вам нужно сделать, это прочитать из stdin.   -  person Henrik    schedule 19.09.2014
comment
Вау, ты потрясающий @Henrik!!!! Я потратил около 9 часов, пытаясь собрать вещи. Я не понимал этого с самого начала, но, увидев эти комментарии от вас, ребята, я, наконец, понял, что конвейер означает связывание команд вместе или вызов другой программы внутри вашей программы.   -  person raffaello    schedule 19.09.2014


Ответы (2)


Это мое предложение, поскольку вы хотели читать и записывать двоичные файлы:

#include <stdio.h>

int main (void) {
    if (!freopen(NULL, "rb", stdin)) {
        return 1;
    }
    if (!freopen(NULL, "wb", stdout)) {
        return 1;
    }

    char buf[4];
    while (!feof(stdin)) {
        size_t numbytes = fread(buf, 1, 4, stdin);

        // Do something with the bytes here...

        fwrite(buf, 1, numbytes, stdout);
    }
}
person Henrik    schedule 19.09.2014
comment
Это то, что я только что сделал :) .. Потребовалось время, чтобы понять, как сделать вывод stdout двоичным. Жаль, что я не посмотрел на это 20 минут назад. - person raffaello; 19.09.2014
comment
Проверка EOF не работает. Вы должны проверить feof() после fread(), но перед fwrite(). Или просто используйте возвращаемое значение fread(). - person FatalError; 19.09.2014
comment
@FatalError Из справочной страницы fread: если возникает ошибка или достигается конец файла, возвращаемое значение представляет собой короткий счетчик элементов (или ноль). т.е. numbytes содержит количество фактически прочитанных байтов, даже если было достигнуто EOF. Эти байты нужно записать. - person Henrik; 19.09.2014
comment
@Henrik: +1 Да, теперь, когда я присмотрелся повнимательнее, ваш код верен. Если при чтении не удается вернуть какие-либо данные, он вызовет fwrite() с 0 байтами, поэтому он фактически не запишет ничего, что находится в buf. - person FatalError; 19.09.2014

Чтобы иметь возможность читать вывод (stdout) cat, вам не нужно передавать в конвейер ничего, что я нашел благодаря вам, ребята! Я запутался с трубами...

поэтому, если вы запустите " cat somefile | program ", где somefile содержит двоичные данные... вы просто увидите, что содержит somefile, перепечатанный на терминале.

Благодарю вас! Теперь я могу закончить писать свой program.

/*program.c*/

int main()
{
    int i, num;

    unsigned char block[2];

    while ((num = fread(block, 1, 2, stdin)) == 2)
    {
        for(i = 0; i < 2; i++)
        {
            printf("%02x", block[i]);
        }
    }

}
person raffaello    schedule 19.09.2014