【问题标题】:Reading a file through STDIN in C在 C 中通过 STDIN 读取文件
【发布时间】:2020-05-08 00:28:30
【问题描述】:

我正在尝试在cmd 中运行以下内容:

gcc my_mainFile

然后运行以下命令:

a.exe 2 < file.ppm

基本上,它的作用是查看值2,基于该值调用特定函数,并使用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
    }
}

【问题讨论】:

  • 这能回答你的问题吗? How to read a file passed through stdin in C
  • 如果您将文件重定向到程序中,则无需打开该文件。只需使用readfgetsscanf 等输入函数之一将数据读入缓冲区或变量。你的问题是不知道如何调用这些函数还是不知道文件内容的格式?
  • 比起你的环形交叉路口if(*argv[1] - '0' == 2,更常见的测试argv实际上只是if (argv[1][0] == '2')的方法...
  • “修改这些值”到底是什么意思?在将它们写入屏幕之前修改它们?或者也在文件中修改它们,即改变文件内容?
  • 我建议在使用argv[] 之前测试argc 的值,以避免使用未提供的参数...

标签: c file input


【解决方案1】:

默认情况下,许多 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() 用于确保每次读取都使用完整的输入行,防止在您的输入流中留下未读取的杂散字符,这将导致您下次尝试读取时读取失败(或无限循环)。该行所需的任何值都使用sscanf 进行解析。这避免了新的 C 程序员在了解如何检测和正确处理 匹配输入 之前尝试直接使用 scanffscanf 阅读而陷入的大量陷阱由于格式说明符和输入之间的不匹配,或者在所有指定的转换发生之前耗尽输入而导致的失败。

示例

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 读取并避免检查是否给出了文件名——但是这种方法为输入处理提供了很多便利和灵活性,只需几个额外的代码行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多