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

C语言输入格式错误时退出程序及字符串输入异常问题排查

问题描述

编写的C语言代码用于读取用户输入的宠物信息(姓名、年龄、种类)并存入数组,通过判断scanf返回值验证输入有效性,格式错误则退出程序。但实际运行时,合法字符串输入会触发"Invalid input for name"错误,仅整数输入功能正常。

代码片段

int petCount = 1;

while (1) {
        if (scanf("%s", array[petCount].name) != 1) {
                printf("Invalid input for name.\n");
                exit(1);
        }
        if (scanf("%d", &array[petCount].age) != 1) {
                printf("Invalid input for age.\n");
                exit(1);
        }
        if (scanf("%s", array[petCount].species) != 1) {
                printf("Invalid input for species.\n");
                exit(1);
        }
        petCount++;
}

for (int i = 1; i < petCount; i++){
        printf("%s, %d, %s\n", array[i].name, array[i].age, array[i].species );
}
free(array);

输入示例

Type name, age, species on each line (press Ctrl+D to finish):
Eve
9
cat

输出结果

Invalid input for name.
问题分析与解决方案

核心问题

  1. 数组索引越界:
    C语言数组默认从索引0开始,代码中petCount初始值为1,第一次循环直接访问array[1]。如果array是按常规方式分配(比如malloc(sizeof(Pet)*maxCount)),此时array[1]可能指向未分配的内存区域,scanf写入时会触发内存异常,导致返回值不符合预期,触发错误提示。

  2. 未处理EOF结束信号:
    用户按Ctrl+D输入EOF时,scanf会返回EOF(值为-1),代码直接判定为输入错误并退出,而非正常结束输入流程。

修复方案

  1. 修正数组索引起始值:
    将petCount初始化为0,循环中使用array[petCount]访问数组元素,确保从合法的起始索引开始写入。

  2. 区分输入错误与EOF:
    判断scanf返回值时,先检查是否为EOF,若是则跳出循环;再验证是否为预期的匹配数量,否则判定为输入错误。

  3. 避免缓冲区溢出(可选但推荐):
    使用scanf读取字符串时,限制输入长度,防止超出name和species的数组容量,例如scanf("%20s", array[petCount].name)(假设数组长度为21,留1位给终止符)。

修正后的代码示例

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

// 假设Pet结构体定义如下
typedef struct {
    char name[21];
    int age;
    char species[21];
} Pet;

int main() {
    int maxPets = 10;
    Pet *array = malloc(sizeof(Pet) * maxPets);
    if (!array) {
        perror("malloc failed");
        exit(1);
    }

    int petCount = 0;
    printf("Type name, age, species on each line (press Ctrl+D to finish):\n");

    while (1) {
        // 处理姓名输入
        int ret = scanf("%20s", array[petCount].name);
        if (ret == EOF) {
            break; // 正常结束输入
        } else if (ret != 1) {
            printf("Invalid input for name.\n");
            free(array);
            exit(1);
        }

        // 处理年龄输入
        ret = scanf("%d", &array[petCount].age);
        if (ret == EOF) {
            printf("Unexpected end of input while reading age.\n");
            free(array);
            exit(1);
        } else if (ret != 1) {
            printf("Invalid input for age.\n");
            free(array);
            exit(1);
        }

        // 处理种类输入
        ret = scanf("%20s", array[petCount].species);
        if (ret == EOF) {
            printf("Unexpected end of input while reading species.\n");
            free(array);
            exit(1);
        } else if (ret != 1) {
            printf("Invalid input for species.\n");
            free(array);
            exit(1);
        }

        petCount++;
        // 检查数组是否已满
        if (petCount >= maxPets) {
            printf("Reached maximum number of pets.\n");
            break;
        }
    }

    // 输出存储的宠物信息
    printf("\nStored pet information:\n");
    for (int i = 0; i < petCount; i++){
        printf("%s, %d, %s\n", array[i].name, array[i].age, array[i].species );
    }

    free(array);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 03:16:13