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

读取文本文件数值到数组出现随机值问题及修复求助

问题修复方案

核心问题分析

你的代码出现随机值/0的主要原因是文件指针未重置,加上类型不匹配、数组操作逻辑错误等问题,逐一修复如下:

1. 重置文件指针到起始位置

checkSize函数读完文件后,文件指针已经指向EOF,后续fscanf无法读取任何内容,导致数组里都是未初始化的垃圾值。在调用checkSize后必须重置指针:

new->size = checkSize(file);
rewind(file); // 重置文件指针到开头

2. 修复行数计数逻辑

checkSize仅通过换行符计数,若文件最后一行没有换行,会少算一行。修改计数逻辑:

int checkSize(FILE* file) { 
    int counter = 0;
    char chr;
    
    if (feof(file)) return 0;
    
    chr = getc(file);
    while (chr != EOF) {
        if (chr == '\n') {
            counter++;
        }
        chr = getc(file);
    }
    // 处理最后一行无换行的情况
    fseek(file, -1, SEEK_END);
    chr = getc(file);
    if (chr != '\n') {
        counter++;
    }
    rewind(file);
    return counter;
}

3. 修正类型匹配问题

  • fscanf用%ld读取int类型数组arrayAux,格式符不匹配,改为%d;
  • void** values存储int值时,不能直接赋值(会把int当作指针地址),需要为每个元素分配内存再存储数值:
// 替换原读取循环
while(i < new->size) {
    int* val = malloc(sizeof(int)); // 为每个int分配内存
    fscanf(file, "%d", val); // 直接读入分配的内存
    new->values[i] = val;
    i++;
}

4. 修复移除前三行的逻辑

原循环逐个替换会导致数据错位且未真正移除前三行,改用内存移动一次性处理:

// 移除前三行,先检查size是否足够3行
if (new->size >= 3) {
    // 把索引3及以后的元素往前移3位
    memmove(new->values, new->values + 3, (new->size - 3) * sizeof(void*));
    // 释放前三行的内存(避免内存泄漏)
    for (int j = 0; j < 3; j++) {
        free(new->values[new->size - 3 + j]);
    }
    new->size -= 3;
}

5. 修正输出循环的越界问题

原循环i <= new->size会访问超出数组范围的元素,改为i < new->size,同时输出时要解引用void*:

for (i = 0; i < new->size; i++) {
    printf("%d\n", *(int*)new->values[i]);
}

6. 其他细节优化

  • 变量名new易混淆,改为newSet;
  • 检查malloc是否成功,避免空指针错误:
Set* newSet = malloc(sizeof(Set));
if (!newSet) return NULL;
newSet->values = malloc(sizeof(void*)*newSet->size);
if (!newSet->values) {
    free(newSet);
    return NULL;
}

完整修复后的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct set{
    void** values;
    int size; 
}Set;

int checkSize(FILE* file) { 
    int counter = 0;
    char chr;
    
    if (feof(file)) return 0;
    
    chr = getc(file);
    while (chr != EOF) {
        if (chr == '\n') {
            counter++;
        }
        chr = getc(file);
    }
    // 处理最后一行无换行的情况
    fseek(file, -1, SEEK_END);
    chr = getc(file);
    if (chr != '\n') {
        counter++;
    }
    rewind(file);
    return counter;
}

Set* readSet(FILE* file){ 
    Set* newSet = malloc(sizeof(Set));
    if (!newSet) return NULL;
    
    newSet->size = checkSize(file);
    newSet->values = malloc(sizeof(void*)*newSet->size);
    if (!newSet->values) {
        free(newSet);
        return NULL;
    }
    
    int i = 0;
    while(i < newSet->size) {
        int* val = malloc(sizeof(int));
        if (!val) {
            // 内存分配失败时释放已分配的资源
            for (int j = 0; j < i; j++) {
                free(newSet->values[j]);
            }
            free(newSet->values);
            free(newSet);
            return NULL;
        }
        fscanf(file, "%d", val);
        newSet->values[i] = val;
        i++;
    }
    
    // 移除前三行
    if (newSet->size >= 3) {
        memmove(newSet->values, newSet->values + 3, (newSet->size - 3) * sizeof(void*));
        // 释放被移除的元素内存
        for (int j = 0; j < 3; j++) {
            free(newSet->values[newSet->size - 3 + j]);
        }
        newSet->size -= 3;
    }
    
    // 输出测试
    for (i = 0; i < newSet->size; i++) {
        printf("%d\n", *(int*)newSet->values[i]);
    }
    
    return newSet;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 07:05:51