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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:03:41