C程序求助:读取标准输入与命令行参数并对比(含编译警告)
解决C程序编译警告与逻辑错误,实现标准输入与命令行参数的相似性对比
编译警告的直接修复
你遇到的atoi类型不匹配警告,根源是两处基础错误:
- main函数中变量赋值错误:
argv是char**类型(命令行参数数组),不能直接赋值给const char*,需改为char** temp = argv; - input_number函数参数传递错误:
atoi需要单个字符串指针char*,而你传入的是char**类型的c,需改为atoi(*c)(取第一个命令行参数)或按需求取对应索引的参数,比如atoi(c[1])取第二个参数。
核心逻辑错误修正
除了编译警告,代码还有多处逻辑问题导致无法正常运行,以下是针对性修复:
1. input_file函数的字符处理错误
- 函数无需传递
char参数,直接从标准输入读取即可,修改函数声明为void input_file(void); strcpy(Contact.name, &file);是严重内存越界错误:&file仅指向单个字符,strcpy会一直读取到\0,破坏内存。需改为逐个字符追加到数组并维护索引:void input_file(void){ int idx = 0; struct persinfo Contact = {0}; // 初始化结构体,避免垃圾值 int ch; while((ch = getchar()) != EOF){ if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')){ if (idx < MAXSIZE -1) { // 留位置给字符串结束符 Contact.name[idx++] = ch; Contact.name[idx] = '\0'; } printf("当前名字: %s\n", Contact.name); } else if (ch >= '0' && ch <= '9'){ Contact.phonumber = Contact.phonumber * 10 + (ch - '0'); // 累积数字 printf("当前手机号: %ld\n", Contact.phonumber); } } }
2. input_number函数的只读内存修改错误
- 不能用
scanf("%c", *c)修改命令行参数内存:argv指向的内存是只读的,强行修改会触发未定义行为。该函数应直接遍历命令行参数,而非读取新输入:void input_number(char **c, int argc){ if (argc < 2) { printf("未提供命令行参数\n"); return; } // 校验第二个参数是否为有效数字 char *endptr; long num = strtol(c[1], &endptr, 10); if (*endptr != '\0'){ printf("错误: %s 不是有效数字\n", c[1]); return; } printf("命令行输入的数字: %ld\n", num); }
3. main函数的参数传递修正
- 修正
temp的类型,调用input_file时无需传递参数:int main(int argc, char *argv[]){ char **temp = argv; input_file(); printf("\n"); input_number(temp, argc); return 0; }
4. find函数的相似性对比使用
你的find函数已实现子串匹配逻辑,只需在获取标准输入内容和命令行参数后调用即可。比如将Contact定义为全局变量,在input_number中添加:
if (find(Contact.name, c[1])) { printf("找到匹配项!\n"); } else { printf("无匹配项.\n"); }
完整修正后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXSIZE 100 struct persinfo { char name[MAXSIZE]; long phonumber; }; // 全局变量,方便跨函数访问标准输入内容 struct persinfo Contact = {0}; void input_file(void); void input_number(char **c, int i); int find(char str[], char ptr[]); int main(int argc, char *argv[]){ char **temp = argv; input_file(); printf("\n"); input_number(temp, argc); return 0; } void input_number(char **c, int argc){ if (argc < 2) { printf("未提供命令行参数\n"); return; } // 校验并转换数字参数 char *endptr; long num = strtol(c[1], &endptr, 10); if (*endptr != '\0'){ printf("错误: %s 不是有效数字\n", c[1]); // 尝试匹配名字 if (find(Contact.name, c[1])) { printf("名字匹配成功!\n"); } else { printf("名字无匹配项.\n"); } return; } printf("命令行输入的数字: %ld\n", num); // 匹配手机号 char num_str[MAXSIZE]; sprintf(num_str, "%ld", Contact.phonumber); if (find(num_str, c[1])) { printf("手机号匹配成功!\n"); } else { printf("手机号无匹配项.\n"); } } void input_file(void){ int idx = 0; int ch; while((ch = getchar()) != EOF){ if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')){ if (idx < MAXSIZE -1) { Contact.name[idx++] = ch; Contact.name[idx] = '\0'; } printf("当前名字: %s\n", Contact.name); } else if (ch >= '0' && ch <= '9'){ Contact.phonumber = Contact.phonumber * 10 + (ch - '0'); printf("当前手机号: %ld\n", Contact.phonumber); } } } int find(char str[], char ptr[]){ int i, j, k; for (i = 0; str[i] != '\0'; ++i){ for (j = i, k = 0; ptr[k] != '\0' && str[j] == ptr[k]; ++j, ++k); if (ptr[k] == '\0') return 1; } return 0; }
关键说明
- 全程未使用
fopen和malloc,符合项目规则 - 修复了内存越界、类型不匹配、只读内存修改等致命问题
- 实现了标准输入内容与命令行参数的双向相似性匹配(名字/手机号)
内容的提问来源于stack exchange,提问作者adamchukk
相关产品推荐
相关产品推荐

