C++中将数组数据写入日志文本文件无内容输出问题
问题现象
开发游戏时其余功能运行正常,需要实现日志写入功能(将数组数据写入文本文件),但数组对应内容始终无法成功写入文件。
相关实现代码如下:
void writeToFile(ofstream &outputfile, string name, string s2, string s3, string s4, string s5) { outputfile << "HI" << endl; outputfile << endl << endl << "The card that you get is: " << name<<" "<<s2<<" "<<s3<<" "<<s4<<" "<<s5<<endl <<endl; } int main () { ofstream outputfile; outputfile.open("program3data.txt"); int randomnumber=random_number(); count=findwords(); k=count; int *sr; sr= new int[count]; string *name; name= new string[count]; string *s2; s2= new string[count]; string *s3; s3= new string[count]; string *s4 ; s4 = new string[count]; string *s5 ; s5 = new string[count]; string *s6 ; s6 = new string[count]; writeToFile(outputfile, name[randomnumber],s2[randomnumber],s3[randomnumber],s4[randomnumber],s5[randomnumber]); }
相关报错截图:
程序预期输出抽到的卡牌对应的数组内容,无法定位故障原因。
故障根因
代码存在4个核心逻辑错误,直接导致写入失败甚至程序崩溃:
- 执行顺序完全错误:先生成随机下标
randomnumber、再调用findwords()获取卡牌总数count,此时count在赋值前是未初始化的垃圾值,后续基于这个垃圾值new出来的数组长度本身就是非法的;更关键的是,new完所有string数组后,根本没有给数组元素填充任何卡牌数据,C++中new出来的std::string默认是空字符串,写进文件自然没有内容。 - 没有做数组边界校验:
randomnumber的生成逻辑没有和实际的卡牌总数count绑定,很容易出现下标大于等于数组长度、或者为负数的情况,触发数组越界,程序会直接崩溃,根本执行不到写文件的逻辑。 - 没有正常关闭文件:写完内容后没有调用文件流的close方法,文件缓冲区的内容可能不会被刷到磁盘上,就算前面逻辑正确,也可能出现文件为空的情况。
- 冗余内存泄漏:new出来的
sr、s6数组全程没有被使用,无意义占用堆内存。
修复方案
按以下顺序调整代码逻辑即可:
- 先调用
findwords()拿到有效、准确的卡牌总数count - 校验count合法性,基于合法的count值初始化所有数组
- 补充卡牌数据读取逻辑,把读取到的所有卡牌名称、属性数据,填充到
name、s2~s5数组的对应下标位置 - 生成范围在
[0, count-1]区间内的合法随机数randomnumber,做边界校验确保不会越界 - 调用
writeToFile写入日志 - 写入完成后调用
outputfile.close()关闭文件,确保缓冲区内容刷到磁盘 - 释放所有new出来的数组内存,避免泄漏
修复后的核心逻辑参考:
int main () { ofstream outputfile; outputfile.open("program3data.txt"); // 先获取有效卡牌总数 int count = findwords(); // 校验数据合法性 if (count <= 0) { outputfile << "No valid card data found" << endl; outputfile.close(); return -1; } int k = count; // 基于合法长度初始化数组 int *sr = new int[count]; string *name = new string[count]; string *s2 = new string[count]; string *s3 = new string[count]; string *s4 = new string[count]; string *s5 = new string[count]; // 此处补充卡牌数据读取逻辑,给name、s2-s5的每个下标元素赋值 // 示例:name[i] = 读取到的第i张卡名称,s2[i] = 第i张卡对应属性,以此类推 // 生成合法范围的随机下标 int randomnumber = random_number() % count; if (randomnumber < 0) randomnumber += count; // 兼容负数随机数场景 // 写入日志 writeToFile(outputfile, name[randomnumber],s2[randomnumber],s3[randomnumber],s4[randomnumber],s5[randomnumber]); // 关闭文件刷盘 outputfile.close(); // 释放堆内存 delete[] sr; delete[] name; delete[] s2; delete[] s3; delete[] s4; delete[] s5; return 0; }
内容的提问来源于stack exchange,提问作者user17108831
相关产品推荐
相关产品推荐

