scanf输入异常,数组去重C语言程序无法正常运行求助
解决数组去重程序中的输入循环与逻辑问题
我帮你排查了代码里的几个核心问题,这些问题组合起来导致了程序无法正常运行,咱们逐个梳理修复:
1. 计算去重数组大小的死循环
你这段计算sub_number的代码里,i没有自增操作,会导致程序一直卡在这个while循环里,永远到不了后续的输出步骤:
while(i < number) { if(*(array + i) != 0) { sub_number++; // 用于指定sub_array的大小 } }
修复方式:在循环体末尾加上i++,让循环能正常推进:
while(i < number) { if(*(array + i) != 0) { sub_number++; } i++; // 必须添加这行,否则循环永不结束 }
2. 输入阶段的无限循环陷阱
如果用户输入数组大小number时不小心输入了非数字字符(比如字母),scanf("%d", &number)会读取失败,输入缓冲区里的无效字符会一直残留,导致后续的scanf也一直读取失败,陷入无限要求输入的情况。
修复方式:检查scanf的返回值,确保读取有效输入,同时清理输入缓冲区的无效内容:
printf("Enter the size of your array\n"); // 确保输入有效的正整数 while(scanf("%d",&number) != 1 || number <= 0) { printf("请输入一个正整数作为数组大小:\n"); // 清理输入缓冲区的无效内容 while(getchar() != '\n'); }
3. 去重逻辑的缺陷(误判原数组中的0)
你用把重复元素设为0的方式去重,但如果原数组本身包含0这个元素,会被误当成重复元素过滤掉,导致丢失原本有效的0值。
修复方式:改用标记数组记录元素是否已经被处理过,避免误判:
// 替换原有的去重循环 int *seen = calloc(number, sizeof(int)); // 标记是否已经处理过该元素 for(i = 0; i < number; i++) { if(seen[i]) continue; // 已经处理过,跳过 for(j = i + 1; j < number; j++) { if(array[i] == array[j]) { seen[j] = 1; // 标记为重复,后续跳过 } } } // 计算sub_number sub_number = 0; for(i = 0; i < number; i++) { if(!seen[i]) sub_number++; }
4. sub_array填充的位置与逻辑
你新增的填充sub_array的代码需要放在sub_array分配内存之后,并且要正确初始化j的值:
int *sub_array = calloc(sub_number, sizeof(int)); j = 0; // 初始化j为0 for(i = 0; i < number ;i++) { if(!seen[i]) { // 使用标记数组判断是否为非重复元素 sub_array[j] = array[i]; j++; } }
5. 内存泄漏问题
动态分配的内存array、seen、sub_array在程序结束前需要释放,避免内存泄漏:
free(array); free(seen); free(sub_array);
完整修正后的代码
#include <stdio.h> #include <stdlib.h> int main() { int number; // 用于指定动态分配数组的大小 printf("Enter the size of your array\n"); // 确保输入有效的正整数 while(scanf("%d",&number) != 1 || number <= 0) { printf("请输入一个正整数作为数组大小:\n"); while(getchar() != '\n'); // 清理输入缓冲区 } int *array = calloc(number, sizeof(int)); // 动态分配内存 if(array == NULL) { printf("内存分配失败!\n"); return 1; } int i,j; // 循环计数器变量 printf("Enter the elements of arrays\n"); for(i = 0; i < number; i++) { // 确保每个元素都能正确读取 while(scanf("%d", &array[i]) != 1) { printf("请输入有效的整数:\n"); while(getchar() != '\n'); } } // 标记数组,记录元素是否重复 int *seen = calloc(number, sizeof(int)); if(seen == NULL) { printf("内存分配失败!\n"); free(array); return 1; } for(i = 0; i < number; i++) { if(seen[i]) continue; for(j = i + 1 ; j < number; j++) { if(array[i] == array[j]) { seen[j] = 1; } } } // 计算去重后的数组大小 int sub_number = 0; for(i = 0; i < number; i++) { if(!seen[i]) { sub_number++; } } // 分配去重后的数组内存 int *sub_array = calloc(sub_number, sizeof(int)); if(sub_array == NULL) { printf("内存分配失败!\n"); free(array); free(seen); return 1; } // 填充去重后的数组 j = 0; for(i = 0; i < number ;i++) { if(!seen[i]) { sub_array[j] = array[i]; j++; } } // 输出结果 printf("去重后的数组元素为:\n"); for(i = 0; i < sub_number; i++) { printf("%d ", sub_array[i]); } printf("\n"); // 释放动态分配的内存 free(array); free(seen); free(sub_array); return 0; }
现在测试这个代码,不管输入是否包含0,还是输入错误的格式,都能正常处理并正确输出去重后的数组。
内容的提问来源于stack exchange,提问作者Swarnim Khosla
相关产品推荐
相关产品推荐

