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

C语言中如何正确将文件单行数字读取到结构体的数组中?

C语言中如何正确将文件单行数字读取到结构体的数组中?

看起来你遇到的问题是把文件里的单行数字读取到结构体的int数组后,得到的全是垃圾值,而且调试时函数内部打印的结果也不对。我帮你排查了几个可能的问题,以及对应的解决办法:

最可能的元凶:UTF-8 BOM字节干扰

如果你是用Windows自带的记事本保存的UTF-8格式文件,文件开头会偷偷加上3个字节的BOM(十六进制是EF BB BF)。这三个字节不是普通空格,strtok会把它们当成第一个"token"的一部分,atoi把这个非数字的字节序列转成了奇怪的大整数(比如你看到的1102871301,正好是0xEFBBBF的十进制值)。而且因为BOM和后面的数字之间没有空格,strtok只会读到这一个错误的token,所以返回的数组长度总是1。

代码里的其他潜在问题

  1. 循环逻辑漏洞:你的keepReading只有在找到目标行时才会设为false,但如果文件的行数比你指定的readLine少,fgets会返回NULL(表示到了文件末尾),这时候lineBuffer里的内容是不确定的,后续处理会读取无效数据。而且你没有检查fgets的返回值,可能会处理到无效的行内容。
  2. 分隔符太局限:你只用" "作为strtok的分隔符,但如果文件里的数字之间有多个空格、制表符(Tab)或者换行符,就会分割失败,导致读取不完整。

修正后的完整代码

我把你的代码做了针对性修改,加上了BOM处理、错误检查和更灵活的分隔符:

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

// 定义结构体
typedef struct mapData {
    int* walls;
    // 可以添加其他成员变量
} mapData;

static mapData currentMap;

void fileToArray(char *fileName, int lineSize, int readLine, int *array, int *returnedArrayLength) {
    FILE *file = fopen(fileName, "r");
    if (file == NULL) {
        printf("Error opening file\n");
        return;
    }

    bool keepReading = true;
    int currentLine = 1;
    char lineBuffer[2048];
    bool foundTargetLine = false;

    while (keepReading) {
        // 先检查fgets是否成功读取到内容,避免处理无效数据
        if (fgets(lineBuffer, sizeof(lineBuffer), file) == NULL) {
            keepReading = false;
            break;
        }

        if (currentLine == readLine) {
            foundTargetLine = true;
            keepReading = false;

            // 处理UTF-8 BOM:如果文件开头有BOM,跳过前3个字节
            char *start = lineBuffer;
            if ((unsigned char)start[0] == 0xEF && (unsigned char)start[1] == 0xBB && (unsigned char)start[2] == 0xBF) {
                start += 3;
            }

            // 用空格、Tab、换行作为分隔符,适配更多场景
            char *token = strtok(start, " \t\n");
            int i = 0;
            while (token != NULL && i < lineSize) {
                array[i++] = atoi(token);
                token = strtok(NULL, " \t\n");
            }

            printf("Returned array length: %d from line: %d\n", i, readLine);
            for (int j = 0; j < i; j++) {
                printf("%d ", array[j]);
            }
            printf("\n");

            if (returnedArrayLength) {
                *returnedArrayLength = i;
            }
        }

        currentLine++;
    }

    // 如果没找到目标行,给出提示
    if (!foundTargetLine) {
        printf("Line %d not found in the file\n", readLine);
    }

    fclose(file);
}

// 主函数示例
int main() {
    int mapSize = 10; // 根据你的实际需求调整数组大小
    int returnedLength;

    // 分配内存时检查是否成功
    currentMap.walls = malloc(mapSize * sizeof(int));
    if (currentMap.walls == NULL) {
        printf("Malloc failed: out of memory\n");
        return 1;
    }

    // 注意第一个参数是你的文件名,比如"map.txt"
    fileToArray("map.txt", mapSize, 1, currentMap.walls, &returnedLength);

    // 打印结构体数组的内容,验证是否正确
    printf("\nStruct array content:\n");
    for (int j = 0; j < returnedLength; j++) {
        printf("%d ", currentMap.walls[j]);
    }
    printf("\n");

    // 记得释放内存,避免内存泄漏
    free(currentMap.walls);
    return 0;
}

额外的注意事项

  1. 文件保存格式:尽量用纯文本编辑器(比如Notepad++)保存文件,选择「UTF-8无BOM」格式,从根源上避免BOM的干扰。
  2. 内存管理:记得在使用完malloc分配的数组后用free释放,避免内存泄漏。
  3. 数组大小:确保mapSize足够大,能容纳文件里的所有数字,避免数组越界。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 10:49:51