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

#c #command-line-arguments #stdin #fopen

#c #аргументы командной строки #stdin #fopen

Вопрос:

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

Когда я загружаю входной файл в программу следующим образом:

 ./sim < ex1_in
  

все работает так, как должно!

Однако, когда я указываю входной файл в качестве аргумента file, например:

 ./sim ex1_in
  

вместо этого программа ищет ввод пользователя.

Это часть кода, которая обрабатывает входные и файловые аргументы:

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

    if (argc > 3) {
        fprintf (stderr, "Error: Too many arguments.n");
        return 1;
    }

    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* check file */
        fprintf (stderr, "Error: File Open Failed '%s'.n", argv[1]);
        return 2;
    }    

    //Initializing array of 256 unsigned chars
    unsigned char binary[256]; 
    int i = 0; 
    unsigned char c;
    int count2 = 0; 


    //populate the 256 byte char array from stdin
    while (count2 < SIZE) {
        c=getchar();
        binary[i] = c;
        i  ;
        count2  ;                   
    }          
  

До сих пор я определял этот while цикл как проблемную область, поскольку, когда я его комментирую, нежелательного поведения не происходит. Но я не уверен, почему это так.

Позже в main методе файл закрывается:

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

Еще одна уместная вещь:

 #define SIZE 256
  

Комментарии:

1. Вы fopen , но я не думаю getchar , что знает о вашем fp указателе. Другие функции были бы лучше.

2. Вы должны использовать SIZE макрос в объявлении binary .

Ответ №1:

getchar() считывает из stdin , но вы должны выполнять весь ввод из fp . Измените getchar() на getc(fp) .

getchar() в основном просто сокращается от getc(stdin) .

Другой способ сделать это — подключиться stdin к файлу вместо использования другой переменной.

 if (argc > 1) {
    freopen(argv[1], "r", stdin);
}
  

Комментарии:

1. И, возможно, проверьте argc и при необходимости назначьте fp stdin.

2. Это исправлено, спасибо! Мне было интересно, нужно ли мне это делать, но я почувствовал, что …fopen (argv [1], «r»): stdin; означало бы, что мне не нужно этого делать.

3. Почему вы так думаете? Программа может открывать файлы и все еще считывать из stdin.

4. @MichaelDorgan Я добавлял это к ответу, пока вы комментировали.

5. Если вы используете второй метод, нет fp . Вы просто читаете из stdin , как обычно.