Чтение файла через STDIN в C - PullRequest
       1

Чтение файла через STDIN в C

0 голосов
/ 22 января 2020

Я пытаюсь запустить следующее в cmd:

gcc my_mainFile

, а затем выполнить следующее:

a.exe 2 < file.ppm

В основном то, что он делает, видит значение 2 на основе этого вызывает специфическую c функцию и использует содержимое файла ppm. Тем не менее, я не знаю, как получить доступ к самому файлу. Мне нужно использовать scanf() для чтения файла, но у меня нет четкого формата.

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

int main(int argc, char *argv[]) {
    if(*argv[1] - '0' == 2){
        //Open and read contents of the file
    }
}

1 Ответ

2 голосов
/ 22 января 2020

Многие Linux утилиты позволяют передавать имя файла для чтения в качестве первого аргумента или чтения из stdin по умолчанию. Это позволяет вам читать из заданного имени файла или направлять или перенаправлять вывод из другого процесса в ваш код на stdin. Чтобы реализовать альтернативу, вы можете воспользоваться тем, что stdin имеет тип FILE*, и просто проверить, был ли задан аргумент имени файла для чтения (и если да, открыть и прочитать из этого файла), или прочитать из stdin с помощью по умолчанию.

Например:

#include <stdio.h>

#define MAXC 1024   /* if you need a constant, #define one (or more) */

int main (int argc, char **argv) {

    char buf[MAXC]; /* buffer to hold entire line (adjust MAXC as needed) */
    /* use filename provided as 1st argument (stdin by default) */
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* validate file open for reading */
        perror ("file open failed");
        return 1;
    }

    while (fgets (buf, MAXC, fp)) {                 /* read each line of input */
        int a, b;                                   /* example variables */
        if (sscanf (buf, "%d %d", &a, &b) == 2) {   /* parse/validate values */
            /* do what you need with your values */
            printf ("a: %d    b: %d\n", a, b);
        }
    }

    if (fp != stdin)   /* close file if not stdin */
        fclose (fp);

    return 0;
}

Выше fgets() используется, чтобы гарантировать, что полная строка на входе потребляется при каждом чтении, предотвращая сохранение непонятных символов на вашем входе поток, который вызовет сбой чтения (или бесконечный l oop) при следующей попытке чтения. Любые значения, необходимые из строки, анализируются с sscanf. Это позволяет избежать большого количества ловушек, в которые попадают новые C программисты, пытаясь читать напрямую с scanf или fscanf, прежде чем понять, как обнаружить и правильно обработать соответствующий или вход сбои из-за несоответствия между спецификатором формата и вводом или исчерпанием ввода до того, как произойдут все указанные преобразования.

Примеры

Ввод трубопровода stdin:

$ printf "1 2\n3 4\n" | ./bin/readfileorstdin
a: 1    b: 2
a: 3    b: 4

Пример входного файла

$ cat dat/2x2.txt
2 4
3 5

Обработка файла напрямую или stdin

Чтение файла напрямую:

$ ./bin/readfileorstdin dat/2x2.txt
a: 2    b: 4
a: 3    b: 5

Перенаправление на stdin:

$ /bin/readfileorstdin < dat/2x2.txt
a: 2    b: 4
a: 3    b: 5

Вам не нужно делать это таким образом, вы можете просто читать из stdin напрямую и избегайте проверки, было ли задано имя файла - но этот метод обеспечивает большое удобство и гибкость для обработки ввода всего за несколько дополнительных строк кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...