Использование stdin в C исключительно через файл в канале

Я написал анализатор файлов для проекта, который анализирует файл, предоставленный в командной строке.

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

При использовании командной строки на основе Linux следующие команды должны давать одинаковые результаты :

  1. ./check infile.txt (Ввод имени файла через командную строку)
  2. ./check < infile.txt
  3. cat infile.txt | ./check

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

Редактировать : я понял, насколько все просто, и опубликовал ответ. Я оставлю это для всех, кому это может понадобиться в какой-то момент.

Всего 2 ответа


Это опасно близко к «Пожалуйста, напишите мне мою программу». Или, возможно, он даже пересек эту черту. Тем не менее, это довольно простая программа.

Мы предполагаем, что у вас есть анализатор, который принимает один аргумент FILE* и анализирует этот файл. (Если вы написали функцию синтаксического анализа, которая принимает имя файла const char* , то это объясняется, почему это плохая идея. Функции должны делать только одно, а «открыть файл и затем проанализировать его» - это две вещи. как только вы напишите функцию, которая выполняет две несвязанные вещи, вы сразу же попадете в ситуацию, когда вы действительно захотите выполнить только одну из них (например, просто проанализировать поток, не открывая файл).

Так что это оставляет нас с:

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "myparser.h"
/* Assume that myparser.h includes
 *    int parseFile(FILE* input);
 * which returns non-zero on failure.
 */

int main(int argc, char* argv[]) {
  FILE* input = stdin;  /* If nothing changes, this is what we parse */
  if (argc > 1) {
    if (argc > 2) {
      /* Too many arguments */
      fprintf(stderr, "Usage: %s [FILE]
", argv[0]);
      exit(1);
    }
    /* The convention is that using `-` as a filename is the same as
     * specifying stdin. Just in case it matters, follow the convention.
     */
    if (strcmp(argv[1], "-") != 0) {
      /* It's not -. Try to open the named file. */
      input = fopen(argv[1], "r");
      if (input == NULL) {
        fprintf(stderr, "Could not open '%s': %s
", argv[1], strerror(errno));
        exit(1);
      }
    }
  }

  return parse(input);
}

Вероятно, было бы лучше упаковать большую часть вышеперечисленного в функцию, которая принимает имя файла и возвращает открытый FILE* .


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

ОТВЕТ:

Вы можете использовать fgets из stdin, а затем, чтобы проверить конец файла, вы можете использовать feof для stdin, используя следующее:

while(!feof(stdin))

Есть идеи?

10000