从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; }
关键修复点说明
- 给
line分配足够大的缓冲区,避免溢出; - 修正
balances的索引逻辑,用bi作为数组下标,确保从0开始赋值; - 声明并初始化所有全局变量(
clients_arr、jj等); - 修复
strncat的字符数参数,避免读取越界; - 补充完整的文件打开、逐行读取逻辑,正确处理换行符;
- 增加空指针检查,防止文件格式错误导致崩溃。
内容的提问来源于stack exchange,提问作者Hadi Ayoub
相关产品推荐
相关产品推荐

