C语言检查输入流是否为空及程序参数读取问题求助
嘿,我来帮你搞定这个C语言程序的问题~ 咱们一步步梳理需求,补全并优化你的代码,同时解决输入流检查的问题。
问题拆解与解决方案
1. 先修正基础格式错误
首先提个关键细节:你的argsTest.json格式不符合JSON规范,键值对应该用冒号:分隔,正确写法是:
{ "a": 2, "b": 3 }
另外你的结构体定义语法有误,我会在后续代码里修正。
2. 实现双输入源支持(argv[] / 标准输入)
核心逻辑是:如果启动程序时传入了命令行参数(argc >= 2),就从argv[1]读取JSON内容;如果没有参数,就读取标准输入流的内容(比如TEST < argsTest.json这种场景)。
3. 检查输入流是否为空的方法
标准输入流是否为空可以通过「预读一个字符再放回」的方式判断,这样既不会破坏输入流内容,又能准确检测是否为空。
完整示例代码(基于cJSON库)
我用常用的cJSON库来做JSON解析,你需要确保编译时链接该库(比如gcc test.c -o TEST -lcjson):
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "cJSON.h" // 修正结构体定义,用typedef简化使用 typedef struct { int a; int b; } Number; // 检查标准输入是否为空的工具函数 int is_stdin_empty() { int ch = getchar(); if (ch == EOF) { return 1; // 输入流为空 } ungetc(ch, stdin); // 将预读的字符放回输入流,不影响后续读取 return 0; } // 解析JSON字符串到Number结构体的函数 int parse_json(const char *json_str, Number *num) { cJSON *root = cJSON_Parse(json_str); if (!root) { fprintf(stderr, "JSON解析失败: %s\n", cJSON_GetErrorPtr()); return -1; } // 提取a和b字段并校验类型 cJSON *a_node = cJSON_GetObjectItem(root, "a"); cJSON *b_node = cJSON_GetObjectItem(root, "b"); if (!a_node || !cJSON_IsNumber(a_node) || !b_node || !cJSON_IsNumber(b_node)) { fprintf(stderr, "JSON格式错误:缺少a/b字段或字段类型不是数字\n"); cJSON_Delete(root); return -1; } num->a = a_node->valueint; num->b = b_node->valueint; cJSON_Delete(root); // 释放JSON解析内存 return 0; } int main(int argc, char **argv) { Number numbers; char json_buf[1024]; // 模拟用固定数组,实际场景可改用动态内存分配 int ret; if (argc >= 2) { // 场景1:从命令行参数读取JSON内容 ret = parse_json(argv[1], &numbers); } else { // 场景2:从标准输入读取,先检查输入流是否为空 if (is_stdin_empty()) { fprintf(stderr, "错误:未提供命令行参数,且标准输入为空\n"); return EXIT_FAILURE; } // 读取标准输入的JSON内容 size_t read_len = fread(json_buf, 1, sizeof(json_buf)-1, stdin); if (read_len == 0) { fprintf(stderr, "读取标准输入失败\n"); return EXIT_FAILURE; } json_buf[read_len] = '\0'; // 确保字符串以结束符收尾 ret = parse_json(json_buf, &numbers); } // 解析成功后执行业务逻辑 if (ret == 0) { printf("解析成功:a=%d, b=%d\n", numbers.a, numbers.b); // 这里可以添加你的计算逻辑,比如示例的result计算 int result = numbers.a + numbers.b; printf("示例计算结果:a+b=%d\n", result); } return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; }
关键细节说明
- 输入流检查:
is_stdin_empty()函数通过getchar()预读一个字符,若读到EOF则说明输入流为空,否则用ungetc()把字符放回,保证后续读取不受影响。 - JSON解析:使用cJSON库处理JSON,它轻量且易用,适合这类场景。
- 双输入源兼容:通过
argc判断是否有命令行参数,分别处理两种输入场景,覆盖你需要的argv[]和<重定向输入的需求。
内容的提问来源于stack exchange,提问作者Haskell-newb
相关产品推荐
相关产品推荐

