You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从argv指定文件或stdin读取?彩票程序stdin传参问题

问题1:实现程序从argv指定文件读取,未指定则从stdin读取

其实核心思路很直白——先看命令行有没有传文件名参数:如果有,就打开对应文件读;如果没有,直接用标准输入stdin就行。关键是把输入源抽象成一个通用的流,这样后面的读取逻辑不用区分是文件还是键盘输入。

给你举个C语言的实际例子,一看就懂:

#include <stdio.h>
#include <stdlib.h>

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

    // 检查有没有传入文件名参数
    if (argc > 1) {
        input_stream = fopen(argv[1], "r");
        if (input_stream == NULL) {
            perror("打开文件失败");
            exit(EXIT_FAILURE);
        }
    } else {
        // 没指定文件,直接用stdin
        input_stream = stdin;
    }

    // 接下来不管输入源是什么,都用这个stream读取就行
    char buffer[256];
    while (fgets(buffer, sizeof(buffer), input_stream) != NULL) {
        // 这里写你的数据处理逻辑
        printf("读到内容:%s", buffer);
    }

    // 注意:如果是自己打开的文件要关闭,stdin不用关
    if (input_stream != stdin) {
        fclose(input_stream);
    }

    return EXIT_SUCCESS;
}

这样不管用户是敲./program myfile.txt还是直接./program(然后手动输入内容),程序都能正常工作。


问题2:重定向stdin时,如何给evaluate_tickets的file参数传值

你的情况是原来靠命令行参数传文件名,现在想用./program < file.txt这种重定向方式,但不知道怎么给evaluate_tickets(file, ...)传参数是吧?分两种情况给你说:

情况1:evaluate_tickets接受FILE*类型参数

如果你的函数是用FILE*来接收输入源的(就像上面例子里的input_stream),那简直完美——当用重定向的时候,直接把stdin传给它就行!

修改下主函数的逻辑就行:

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

    if (argc > 1) {
        input_file = fopen(argv[1], "r");
        if (!input_file) {
            perror("打开文件失败");
            exit(EXIT_FAILURE);
        }
    } else {
        // 重定向的时候,stdin就是file.txt的内容,直接传
        input_file = stdin;
    }

    // 直接把input_file传给你的函数
    evaluate_tickets(input_file, lottery_numbers, winner, ...);

    // 非stdin的文件记得关闭
    if (input_file != stdin) fclose(input_file);
}

这样不管用户用命令行参数还是重定向,函数都能正常读取数据,因为stdin本身就是一个合法的FILE*对象,和你打开的文件指针没区别。

情况2:evaluate_tickets必须接收文件名(字符串)

如果你的函数设计成必须传文件名(比如它内部要自己打开文件),那重定向的方式本身没法让程序知道stdin对应的是哪个文件——因为重定向是Shell帮你做的,程序本身看不到文件名。

这时候有个常用的小技巧:约定用"-"作为stdin的占位符。比如修改你的函数:

#include <string.h>

void evaluate_tickets(const char *filename, ...) {
    FILE *fp;
    if (strcmp(filename, "-") == 0) {
        // 用户传了"-",就用stdin读取
        fp = stdin;
    } else {
        fp = fopen(filename, "r");
        if (!fp) { /* 这里加错误处理 */ }
    }

    // 后面的读取逻辑就统一用fp就行
    // ...
}

然后用户就可以两种方式运行:

  • 原来的方式:./program arg1 arg2
  • 重定向等价方式:./program - < file.txt(或者直接敲./program -,然后手动输入内容)

或者你也可以直接用问题1的解决方案,让程序自动判断是用文件还是stdin,这样用户不用特意传"-",直接./program < file.txt就行——前提是你把主函数的输入源处理好,再把对应的FILE*传给函数(如果能改函数参数的话,这是最优解)。


内容的提问来源于stack exchange,提问作者cgalvezg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:20:03