C++文件读取异常:读取到默认值-107374176而非文件内容
问题分析与修复方案
核心错误原因
- 同时读写同一文件的截断冲突:打开输入流
fin后立刻用ios::trunc打开输出流fout,这个标记会直接清空payment.txt内容,导致后续fin读取的是空文件,读到的-107374176是未初始化变量的垃圾值。 - 错误的循环终止逻辑:
while(!fin.eof())的写法会导致读取失败后仍执行一次循环体,输出无效垃圾数据。 - 变量未初始化:
userName、payOff等变量未初始化,读取失败时会携带垃圾值写入文件。 - 输出无换行:写入文件时未添加换行符,会破坏原始文件的行结构。
修复后的代码
#include <vector> #include <fstream> #include <string> #include <iostream> // 定义结构体统一存储支付记录 struct PaymentRecord { std::string userName; float payOff; float monthly; }; void Customer::makePayment() { std::vector<PaymentRecord> records; std::string userName; float payOff, monthly, payment; const std::string PAYMENT = "payment.txt"; // 第一步:读取所有记录到内存 std::ifstream fin(PAYMENT); if (!fin.is_open()) { std::cout << "FILE NOT FOUND\n"; return; } // 正确读取循环:直接判断读取操作是否成功 while (fin >> userName >> payOff >> monthly) { records.push_back({userName, payOff, monthly}); } fin.close(); // 第二步:定位当前用户并修改记录 bool userFound = false; for (auto& record : records) { if (record.userName == this->userName) { std::cout << "payment amount: $"; std::cin >> payment; record.payOff -= payment; userFound = true; break; // 假设单用户仅一条记录,找到后退出循环 } } if (!userFound) { std::cout << "User not found in payment records\n"; return; } // 第三步:将修改后的记录写回文件 std::ofstream fout(PAYMENT); if (!fout.is_open()) { std::cout << "FILE NOT FOUND\n"; return; } for (const auto& record : records) { fout << record.userName << " " << record.payOff << " " << record.monthly << "\n"; } fout.close(); }
关键修改说明
- 分离读写流程:先把文件内容全部读到内存容器,修改完成后再一次性写回,彻底避免同时读写同一文件的冲突。
- 修正读取循环:用
while(fin >> ...)直接判断读取是否成功,规避eof()的逻辑陷阱。 - 结构化管理数据:用
PaymentRecord结构体封装每条记录,避免零散变量的垃圾值问题,代码可读性更强。 - 保留文件格式:写入时添加
\n,维持原始文件的行结构。 - 增强健壮性:增加用户不存在的提示,提前终止无效流程。
内容的提问来源于stack exchange,提问作者Kaiden Seymour
相关产品推荐
相关产品推荐

