C++有序数值文件合并程序问题:循环异常与文件读取困惑
合并两个有序数值文件的问题修复
原代码的核心问题
错误的
eof()使用逻辑while (!f.eof() && !g.eof())的判断完全不可靠——eof()标志只有在尝试读取超出文件末尾时才会被触发。当文件最后一个数值读取成功后,eof()依然为false,循环会多执行一次,此时读取失败得到无效值,导致逻辑混乱。冗余且危险的数值读取方式
用固定长度字符数组读取整数再转int,不仅多余,还可能因数值长度超过数组大小导致内存溢出,atoi处理失败时还会返回0,干扰正常数值比较。内层循环逻辑缺陷
内层while (f_ <= g_)没有判断文件是否已读完,当f文件耗尽后,f_会保留旧值(或atoi返回的0),可能陷入死循环或错误的数值比较;同时if (f_ != g_)的判断会丢弃重复值,若需求是保留所有有序数值,这是错误的。未处理剩余数据
当其中一个文件读完后,另一个文件的剩余有序数值完全没有被写入结果文件。
修正后的代码
#include <iostream> #include <fstream> using namespace std; int main() { ofstream ff("ff.txt"); ifstream f("f.txt"), g("g.txt"); // 检查所有文件是否成功打开 if (!f.is_open() || !g.is_open() || !ff.is_open()) { cout << "文件打开失败" << endl; return 1; } int f_val, g_val; // 用读取操作的返回值判断是否读取成功 bool has_f = (f >> f_val); bool has_g = (g >> g_val); // 合并两个文件的有序数值 while (has_f && has_g) { if (f_val <= g_val) { ff << f_val << endl; // 加换行让输出文件更易读,可按需移除 has_f = (f >> f_val); } else { ff << g_val << endl; has_g = (g >> g_val); } } // 处理f文件剩余的数值 while (has_f) { ff << f_val << endl; has_f = (f >> f_val); } // 处理g文件剩余的数值 while (has_g) { ff << g_val << endl; has_g = (g >> g_val); } // 文件会在对象销毁时自动关闭,显式关闭也可 f.close(); g.close(); ff.close(); return 0; }
关键修正点说明
- 直接读取整数:用
int类型直接读取文件数值,避免字符数组转换的风险和冗余操作。 - 可靠的读取状态判断:
has_f = (f >> f_val)利用流操作的返回值判断读取是否成功——流对象转换为bool时,仅当读取有效且未到末尾时为true,比eof()准确得多。 - 清晰的合并逻辑:每次比较当前读取的两个数值,写入较小的那个后读取下一个值,直到其中一个文件耗尽。
- 处理剩余数据:单独循环处理未耗尽文件的剩余数值,确保所有有序数据都被写入结果。
若需去重合并(相同数值仅保留一次)
修改核心合并循环即可:
while (has_f && has_g) { if (f_val < g_val) { ff << f_val << endl; has_f = (f >> f_val); } else if (f_val > g_val) { ff << g_val << endl; has_g = (g >> g_val); } else { // 数值相同时仅写入一次,同时跳过两个文件中的该值 ff << f_val << endl; has_f = (f >> f_val); has_g = (g >> g_val); } }
内容的提问来源于stack exchange,提问作者Andrii Yavorovskii
相关产品推荐
相关产品推荐

