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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 12:55:18