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

从TXT文件读取整数数组后打印出现随机数的问题求助

问题排查与修复方案

核心问题分析

你遇到的随机数问题本质是内存越界访问和未定义行为,以下是代码中的关键错误:

  • 缓冲区溢出:line数组大小不足
    char line[] = "";定义的数组仅能容纳1个字符(空终止符),但文件中每行内容远长于此。读取文件行时会直接越界写入,破坏其他变量(比如balances数组)的内存,导致后续读取出现随机值。不同环境(CMD/CLion)内存布局不同,所以表现出差异。

  • 数组索引错误:balances赋值越界
    accountsNumber初始为0,匹配"balance"后先执行accountsNumber++,此时accountsNumber=1,然后赋值balances[accountsNumber]——但数组索引从0开始,这会直接访问balances[1],而第一个账户的余额应该存在balances[0],最终导致balances[0]未初始化,出现随机值。同时printf里的balances[ii]是未定义变量,属于无效引用。

  • 未声明的全局变量
    代码中jj、ii、clients数组都没有声明,属于未定义行为,编译器可能会随机分配内存位置,进一步破坏数据。

  • strncat参数错误
    strncat(clients[jj].actions, " ", 2);中,第三个参数是要复制的字符数,但" "只有1个有效字符,传2会读取超出字符串的内存,引入垃圾数据。

  • 缺少文件读取逻辑
    当前readFile函数没有打开文件、逐行读取的代码,这部分实现的缺失会直接导致无法正确加载文件内容。


修复后的代码示例

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

#define SIZE 100  // 根据实际需求调整大小,确保足够容纳数据

typedef struct clientsStruct {
    int id;
    char actions[SIZE];
} clients;

// 调整line大小,足够容纳单行内容
char line[SIZE] = "";
long balances[SIZE];
int bi = 0; // 初始化balance数组的索引
int accountsNumber = 0;
int clientsNumber = 0;
clients clients_arr[SIZE]; // 声明clients数组
int jj = 0; // 初始化clients数组索引

void readFile(const char* filename) {
    FILE* fp = fopen(filename, "r");
    if (!fp) {
        perror("Failed to open file");
        return;
    }

    // 逐行读取文件
    while (fgets(line, sizeof(line), fp) != NULL) {
        // 去掉换行符(替代原错误的尾空格处理)
        size_t len = strlen(line);
        if (len > 0 && line[len-1] == '\n') {
            line[len-1] = '\0';
        }

        char splitter[] = " ";
        char *ptr = strtok(line, splitter);

        while(ptr != NULL) {
            if (strcmp(ptr, "balance") == 0) {
                ptr = strtok(NULL, splitter);
                if (!ptr) break; // 防止格式错误导致空指针

                // 用bi作为索引,先赋值再计数
                balances[bi] = strtol(ptr, NULL, 0);
                printf("**************** balance: %ld - accountsNumber: %d****************\n", balances[bi], accountsNumber+1);
                bi++;
                accountsNumber++;
            }
            else if (strstr(ptr, "client") != NULL) {
                clientsNumber++;
                // 初始化actions数组,避免残留垃圾数据
                memset(&clients_arr[jj].actions, 0, sizeof(clients_arr[jj].actions));
                clients_arr[jj].id = clientsNumber;

                ptr = strtok(NULL, splitter);
                while (ptr) {
                    strncat(clients_arr[jj].actions, ptr, strlen(ptr));
                    ptr = strtok(NULL, splitter);
                    if (ptr != NULL) {
                        // 正确传递要复制的字符数:1
                        strncat(clients_arr[jj].actions, " ", 1);
                    }
                }
                jj++;
            }
            ptr = strtok(NULL, splitter);
        }
    }
    fclose(fp);
}

// 测试打印函数
void printBalances() {
    printf("\nAll balances:\n");
    for (int i = 0; i < accountsNumber; i++) {
        printf("Account %d: %ld\n", i+1, balances[i]);
    }
}

int main() {
    readFile("test.txt");
    printBalances();
    return 0;
}

关键修复点说明

  1. 给line分配足够大的缓冲区,避免溢出;
  2. 修正balances的索引逻辑,用bi作为数组下标,确保从0开始赋值;
  3. 声明并初始化所有全局变量(clients_arr、jj等);
  4. 修复strncat的字符数参数,避免读取越界;
  5. 补充完整的文件打开、逐行读取逻辑,正确处理换行符;
  6. 增加空指针检查,防止文件格式错误导致崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 16:35:22