Использование stdin в C исключительно через файл в канале - PullRequest
1 голос
/ 11 февраля 2020

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

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

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

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

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

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

Ответы [ 2 ]

0 голосов
/ 11 февраля 2020

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

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

Так что у нас остается with:

#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]\n", 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\n", argv[1], strerror(errno));
        exit(1);
      }
    }
  }

  return parse(input);
}

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

0 голосов
/ 11 февраля 2020

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

ОТВЕТ:

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

while(!feof(stdin))
...