应统一用 std::getline(std::cin, line) 读整行并检查流状态,避免混用 >> 和 getline;ofstream 追加须显式指定 std::ios::app,写入后需检查 fout 状态而非仅 is_open()。

用 std::getline 配合 std::ofstream 以 std::ios::app 模式打开文件,就能安全地逐行追加输入——关键不是循环结构本身,而是流状态管理和换行处理。
为什么 while (std::cin >> str) 会丢内容?
这个写法跳过所有空白(包括换行),且遇到非数字输入或 EOF 后 std::cin 进入失败状态,后续 std::getline 直接返回空。更糟的是,它根本读不到含空格的整行。
实操建议:
- 一律改用
std::getline(std::cin, line)读整行,不跳过空格、不截断 - 每次读完立刻检查:
if (!std::cin) break;,否则残留失败位会让下一次读取静默失败 - 别混用
>>和getline在同一输入流上——>>留下的换行符会被下个getline当成空行读出
std::ofstream 追加模式必须显式指定 std::ios::app
默认构造或只传路径的 std::ofstream 是覆盖模式。即使文件已存在,不加标志就会清空重写。
实操建议:
- 打开时务必写全:
std::ofstream fout("log.txt", std::ios::app); - 不要依赖
fout.is_open()就认为能写——追加模式下若磁盘满或权限不足,is_open()仍可能返回true,但写入会失败 - 每次写完检查:
if (!fout) { /* 处理写入失败 */ },尤其在循环中
换行符要自己加,std::getline 不带 \n, 也不自动补
std::getline 读入时把换行符剥离了,而 operator 写字符串时不会额外加 <code>\n。结果就是所有输入挤在同一行。
实操建议:
- 写完每行后手动加:
fout - 别用
std::endl替代'\n'——它强制刷新缓冲区,频繁追加时性能明显下降 - 如果输入本身末尾有
\r\n(Windows 控制台),std::getline已将其统一处理为\n剥离,你只需补一个\n即可,不用判断平台
最常被忽略的是流错误状态的累积:一次读失败没清标志,后面所有读都失效;一次写失败没检查,日志就悄悄断在某一行。控制台输入 + 文件追加看着简单,实际是两层独立的 I/O 状态需要分别兜底。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











