C++使用ifstream读取多TXT文件存入数组后内容异常问题
问题原因分析与解决办法
这个问题本质是指针指向同一块内存导致的经典坑,我来给你拆解清楚:
为什么会出现所有元素都是最后一个文件内容?
你代码里的array[i-1] = str;这行,根本不是把str里的文本内容复制到数组元素里,而是把str这个char数组的内存起始地址赋值给了array的每个指针元素。
而str是在main函数里定义的局部数组,它的内存地址从程序运行到结束都是固定不变的。每次循环读取新文件时,都是把新内容覆盖到同一个str的内存空间里。循环结束后,array里所有的指针都指向同一块内存——也就是最后一次写入的str的内容,自然打印出来全都是最后一个文件的内容了。
至于循环内打印正常,是因为每次读取后立即打印时,str里的内容刚好是当前文件的内容,但这只是临时的,下一次循环就会被覆盖。
怎么解决这个问题?
有两种常用的方案,推荐第一种,更安全省心:
方案1:改用std::string存储(推荐)
std::string会自动管理内存,赋值的时候是复制内容而不是地址,完全避免指针的坑。修改后的代码大概是这样:
#include <iostream> #include <fstream> #include <string> int main() { std::string array[10]; // 用string数组替代char*数组 for(int i=1; i<=10; i++){ // 注意循环范围要包含test10.txt,原来的i<10只到test9.txt std::string filePath = "Test" + std::to_string(i) + ".txt"; std::ifstream openFile(filePath); if(openFile.is_open()){ std::string content; openFile >> content; array[i-1] = content; // 这里是复制内容,不是地址 std::cout << array[i-1] << std::endl; openFile.close(); } } std::cout << array[0] << std::endl; // 输出test1.txt的内容 std::cout << array[5] << std::endl; // 输出test6.txt的内容 std::cout << array[9] << std::endl; // 输出test10.txt的内容 }
如果想用vector的话,改成std::vector<std::string> vec;然后vec.push_back(content);就行,逻辑是一样的。
方案2:手动为每个char*分配独立内存(适合必须用C风格字符串的场景)
如果一定要用char*数组,那得给每个数组元素单独分配内存,然后把str的内容复制过去,而不是直接赋值地址:
#include <iostream> #include <fstream> #include <string> #include <cstring> // 要包含strlen、strcpy的头文件 int main() { char* array[10]; char str[100]; for(int i=1; i<=10; i++){ std::string filePath = "Test" + std::to_string(i) + ".txt"; std::ifstream openFile(filePath); if(openFile.is_open()){ openFile >> str; // 为当前元素分配足够的内存(长度+1是给结束符'\0'留位置) array[i-1] = new char[strlen(str) + 1]; strcpy(array[i-1], str); // 把str的内容复制到新内存里 std::cout << array[i-1] << std::endl; openFile.close(); } } // 打印测试 std::cout << array[0] << std::endl; std::cout << array[5] << std::endl; std::cout << array[9] << std::endl; // 记得释放内存,避免内存泄漏! for(int i=0; i<10; i++){ delete[] array[i]; } }
这种方式要注意手动管理内存,用完必须释放,不然会有内存泄漏问题。
总结
核心问题就是不要让多个指针指向同一块可变的内存空间,要么用自动管理内存的std::string,要么手动为每个指针分配独立的内存来存储内容。
内容的提问来源于stack exchange,提问作者TAYTAY1313
相关产品推荐
相关产品推荐

