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.
问题分析与解决方案
核心问题
数组索引越界:
C语言数组默认从索引0开始,代码中petCount初始值为1,第一次循环直接访问array[1]。如果array是按常规方式分配(比如malloc(sizeof(Pet)*maxCount)),此时array[1]可能指向未分配的内存区域,scanf写入时会触发内存异常,导致返回值不符合预期,触发错误提示。未处理EOF结束信号:
用户按Ctrl+D输入EOF时,scanf会返回EOF(值为-1),代码直接判定为输入错误并退出,而非正常结束输入流程。
修复方案
修正数组索引起始值:
将petCount初始化为0,循环中使用array[petCount]访问数组元素,确保从合法的起始索引开始写入。区分输入错误与EOF:
判断scanf返回值时,先检查是否为EOF,若是则跳出循环;再验证是否为预期的匹配数量,否则判定为输入错误。避免缓冲区溢出(可选但推荐):
使用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
相关产品推荐
相关产品推荐

