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

为何在printf中使用变量i作为Names数组下标时显示异常?

问题分析与修复方案

核心问题根源

  • 动态数组初始分配无效:main函数里用calloc(NumberOfFood, ...)时,NumberOfFood初始值是0,导致所有动态数组(Rno、Price、Quantity、Names等)都没分配内存空间。后续在ReadFile里直接写入Rno[*NumOfFood]属于内存越界访问,会打乱内存结构,遍历输出时自然出现乱码。
  • 文件读取逻辑错误:
    • 用feof(fp)作为循环终止条件时机不对,feof只有在读取到文件末尾后才会触发,会导致循环多执行一次,写入无效数据。
    • fscanf格式字符串有问题:%20[^\n]会读取到换行符前的所有字符,但末尾的\n无法正确匹配换行,导致下一次读取拿到空内容或错误数据;同时%[^\n]的宽度没留足字符串结束符的空间。
    • ReadFile开头有多余的malloc操作,此时getname等变量都是未初始化的垃圾值,malloc的长度完全无效。

修复步骤

1. 修正动态数组的扩容逻辑

因为不知道文件里有多少条数据,需要在每次读取一条数据时对数组进行扩容。要注意,realloc会改变指针本身的值,所以ReadFile的参数要改成二级指针:

// 调整ReadFile的参数类型
void ReadFile(int*NumOfFood, int**Rno, char***Names, int**Price, int**Quantity, char***mfg, char***exp)

在main里调用时要传指针的地址:

ReadFile(&NumberOfFood, &Rno, &Names, &Price, &Quantity, &MFG, &EXP);

在ReadFile的循环内,每次读取数据前扩容数组:

// 扩容int类型数组
*Rno = realloc(*Rno, (*NumOfFood + 1) * sizeof(int));
*Price = realloc(*Price, (*NumOfFood + 1) * sizeof(int));
*Quantity = realloc(*Quantity, (*NumOfFood + 1) * sizeof(int));
// 扩容char指针数组
*Names = realloc(*Names, (*NumOfFood + 1) * sizeof(char*));
*mfg = realloc(*mfg, (*NumOfFood + 1) * sizeof(char*));
*exp = realloc(*exp, (*NumOfFood + 1) * sizeof(char*));

2. 修正文件读取逻辑

  • 用fscanf的返回值判断是否读取成功,而不是feof:
// 调整格式字符串,宽度比数组小1,留足\0的空间,去掉末尾的\n
while (fscanf(fp, "%d %19[^\n] %d %d %19[^\n] %9[^\n]", &rno, getname, &price, &quantity, getmfg, getexp) == 6) {
    // 处理数据的逻辑
}
  • 删除ReadFile开头多余的malloc代码,这部分完全没用还会造成内存泄漏。

3. 补充内存释放(避免泄漏)

在main函数最后,要手动释放所有动态分配的内存:

for(int i=0; i<NumberOfFood; i++) {
    free(Names[i]);
    free(MFG[i]);
    free(EXP[i]);
}
free(Rno);
free(Price);
free(Quantity);
free(Names);
free(MFG);
free(EXP);

完整修复后的代码示例

ReadFile函数

void ReadFile(int*NumOfFood, int**Rno, char***Names, int**Price, int**Quantity, char***mfg, char***exp) {
    char getexp[20], getmfg[20], getname[20];
    int rno, price, quantity;
    FILE* fp = fopen("MyFood1.txt", "r");
    if(!fp) {
        perror("打开文件失败");
        return;
    }

    while (fscanf(fp, "%d %19[^\n] %d %d %19[^\n] %9[^\n]", &rno, getname, &price, &quantity, getmfg, getexp) == 6) {
        // 扩容所有动态数组
        *Rno = realloc(*Rno, (*NumOfFood + 1) * sizeof(int));
        *Price = realloc(*Price, (*NumOfFood + 1) * sizeof(int));
        *Quantity = realloc(*Quantity, (*NumOfFood + 1) * sizeof(int));
        *Names = realloc(*Names, (*NumOfFood + 1) * sizeof(char*));
        *mfg = realloc(*mfg, (*NumOfFood + 1) * sizeof(char*));
        *exp = realloc(*exp, (*NumOfFood + 1) * sizeof(char*));

        // 为字符串分配内存并复制
        (*Names)[*NumOfFood] = malloc(strlen(getname) + 1);
        (*mfg)[*NumOfFood] = malloc(strlen(getmfg) + 1);
        (*exp)[*NumOfFood] = malloc(strlen(getexp) + 1);

        // 赋值
        (*Rno)[*NumOfFood] = rno;
        (*Price)[*NumOfFood] = price;
        (*Quantity)[*NumOfFood] = quantity;
        strcpy((*Names)[*NumOfFood], getname);
        strcpy((*mfg)[*NumOfFood], getmfg);
        strcpy((*exp)[*NumOfFood], getexp);

        (*NumOfFood)++;
    }
    fclose(fp);
}

main函数

int main() {
    int NumberOfFood = 0;

    // 初始化为空指针,后续通过realloc扩容
    int* Rno = NULL;
    int* Price = NULL;
    int* Quantity = NULL;
    char** Names = NULL;
    char** MFG = NULL;
    char** EXP = NULL;

    ReadFile(&NumberOfFood, &Rno, &Names, &Price, &Quantity, &MFG, &EXP);
    DisplayFood(&NumberOfFood, Rno, Names, Price, Quantity, MFG, EXP);

    // 释放所有动态分配的内存
    for(int i=0; i<NumberOfFood; i++) {
        free(Names[i]);
        free(MFG[i]);
        free(EXP[i]);
    }
    free(Rno);
    free(Price);
    free(Quantity);
    free(Names);
    free(MFG);
    free(EXP);

    return 0;
}

DisplayFood函数(微调排版)

void DisplayFood(int*NumOfFood, int*Rno, char *Names[], int*Price, int*Quantity, char*mfg[], char*exp[]) {
    for(int i=0; i<*NumOfFood; i++) {
        printf("\n%-20d %-20s %-20d %-20s %-10s %-20d", 
               Rno[i], Names[i], Price[i], mfg[i], exp[i], Quantity[i]);
    }
    printf("\n");
}

内容的提问来源于stack exchange,提问作者Trương Công Trình

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 11:10:48