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

C语言文件处理程序Bug求助:删除最大负数逻辑异常

C语言代码删除最大负数逻辑错误排查与修复

问题背景

需求:文件中每行最多含30个整数,需删除每行的最大负数;若该行所有负数相同或仅含一个负数,则不执行删除操作。

当前代码处理输入行:

1 2 -4 5 2 -4 6 -4 10 5 6 -7 -7 9 -8

时,未按预期删除最大负数(-4),反而删除了最后一个负数(-8),且该错误仅在存在重复负数时出现。

原代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned read_string(int*, FILE*);
void print(int*, unsigned, FILE*);
void remove_max_negative(int*, unsigned*);
int main() {
    int values[30], s;
    unsigned size, n = 1;
    FILE* file = fopen("1.txt", "r");
        if(!file){
        printf("error");
        return 1;
        }
    FILE* out = fopen("r.txt", "w");
        if(!out){
        printf("error");
        return 1;
        }
    while (size = read_string(values, file)) {
        remove_max_negative(values, &size);
        print(values, size, out);
    }
    fclose(file);
    fclose(out);
    remove("1.txt");
    rename("r.txt", "1.txt");
    return EXIT_SUCCESS;
}
unsigned read_string(int* values, FILE* stream) {
    char value[1024];
    unsigned result = 0;
    fscanf(stream, "%s", value);
    while (!feof(stream)) {
        values[result] = atoi(value);
        result++;
        if (getc(stream) == '\n') return result;
        fscanf(stream, "%s", value);
    }
    return result;
}
void print(int* values, unsigned size, FILE* output) {
    for (int i = 0; i < size; i++) {
        fprintf(output, "%d ", values[i]);
    }
    fprintf(output, "\n");
}
void remove_max_negative(int* values, unsigned* size) {
    int max_value = -2147483648, flag = 0, index_max_value = -1;
    for (int i = 0; i < *size; i++) {
        if (values[i] < 0) {
            if (values[i] > max_value) {
                flag = 0;
                max_value = values[i];
                index_max_value = i;
            }
            else if (values[i] == max_value) {
                flag = 1;
                index_max_value = i;
            }
            else if (flag) {
                index_max_value = i;
            }
        }
    }if (index_max_value != -1) {
        --* size;
        for (int i = index_max_value; i < *size; i++) {
            values[i] = values[i + 1];
        }
    }
}

错误原因分析

  1. 逻辑混乱的下标更新:在remove_max_negative函数中,当遇到比当前max_value更小的负数时,若flag为1,错误地将index_max_value更新为当前下标,这直接导致遍历到最后一个负数时,下标被覆盖为最后一个负数的位置。
  2. 未处理需求中的跳过条件:原代码完全没有判断「所有负数相同」或「仅一个负数」的情况,只要存在负数就执行删除操作,违反需求。

修复方案

重写remove_max_negative函数,分三步实现逻辑:

  1. 遍历数组,统计负数总数、最大负数的值及其出现次数
  2. 判断是否满足删除条件:负数总数>1,且最大负数的出现次数≠负数总数(即不是所有负数都相同)
  3. 找到第一个最大负数的下标,执行删除操作

修复后的remove_max_negative函数:

void remove_max_negative(int* values, unsigned* size) {
    int max_neg = -2147483648;
    int neg_count = 0;
    int max_neg_count = 0;
    int target_index = -1;

    // 第一步:统计负数信息
    for (int i = 0; i < *size; i++) {
        if (values[i] < 0) {
            neg_count++;
            if (values[i] > max_neg) {
                max_neg = values[i];
                max_neg_count = 1;
                target_index = i;
            } else if (values[i] == max_neg) {
                max_neg_count++;
            }
        }
    }

    // 第二步:判断是否需要删除
    if (neg_count <= 1 || max_neg_count == neg_count) {
        return; // 不满足删除条件,直接返回
    }

    // 第三步:执行删除操作
    if (target_index != -1 && target_index < *size) {
        --*size;
        for (int i = target_index; i < *size; i++) {
            values[i] = values[i + 1];
        }
    }
}

验证结果

用示例输入测试,修复后的代码会删除第一个出现的最大负数-4,输出结果为:

1 2 5 2 -4 6 -4 10 5 6 -7 -7 9 -8

符合需求预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 07:45:36