繁体   English   中英

通过管道输入文件在 C 中专门使用 stdin

[英]Using stdin in C exclusively through a piped in file

我为一个项目编写了一个文件解析器,用于解析命令行上提供的文件。

但是,我也希望允许用户通过 stdin输入他们的输入,但只能通过命令行重定向。

使用基于 Linux 的命令提示符,以下命令应该产生相同的结果

  1. ./check infile.txt (通过命令行输入文件名)
  2. ./check < infile.txt
  3. cat infile.txt | ./check

可执行文件应接受文件名作为第一个也是唯一的命令行参数。 如果未指定文件名,则应从标准输入读取。

编辑:我意识到它真的很简单,并发布了一个答案。 我会把这个留给任何可能在某个时候需要它的人。

我想我的大脑被炸了,因为这是一个非常基本的问题,我在发布后立即意识到了这一点。 我会把它留给可能需要它的其他人。

回答:

您可以从 stdin 获取fgets ,然后检查文件的末尾,您仍然可以使用以下命令将feof用于 stdin:

while(!feof(stdin))

这与“请为我编写程序”非常接近。 或者它甚至越过了那条线。 尽管如此,它仍然是一个非常简单的程序。

我们假设您有一个解析器,它接受单个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]\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*

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM