最稳妥做法是用std::vector存每行并逆序遍历输出;std::getline天然兼容换行符,避免operator>>和手动find(' ')的错误;反向迭代器比std::reverse更高效且不修改原数据。

读取时就用 std::vector<:string></:string> 存每行
直接按行读入、逆序遍历输出是最稳妥的做法,避免对单个长字符串做复杂切分。C++ 的 std::getline 天然适配换行符,不会丢空行或误吞
(Windows 下也兼容)。
常见错误是用 operator>> 读字符串——它遇空白就停,根本读不到完整一行;还有人试图用 std::string::find('
') 手动拆分,结果忽略最后一行没换行符的边界情况。
- 用
std::vector<:string> lines</:string>存所有行 - 循环中调用
std::getline(std::cin, line),检查返回值是否为true(防止 EOF 或读取失败) - 读完后用反向迭代器
lines.rbegin()到lines.rend()输出
std::reverse 不适合“按行倒序”,只翻转单个字符串内部字符
有人看到“倒序”第一反应是 std::reverse,但它作用在容器或字符串内部,比如把 "abc
def" 变成 "fed
cba",不是你想要的“第三行→第二行→第一行”效果。
真正需要的是行顺序的反转,不是字符顺序。别在 std::string 上调 std::reverse,除非你真想把每行文字也反过来写。
立即学习“C++免费学习笔记(深入)”;
-
std::reverse(lines.begin(), lines.end())是合法的,但没必要——直接反向遍历更高效、不改原数据 - 若输入来自文件,且内存受限,可考虑双端队列
std::deque+ 前插(push_front),省掉最后反转步骤
处理 Windows 换行符
时,std::getline 自动剥离
std::getline 默认以 '
' 为分隔符,并自动丢弃结尾的
(或
中的
),所以你拿到的每行字符串末尾不会有
。不需要手动 erase 或 substr 处理。
但如果你从二进制模式读文件、或用其他方式构造字符串,就可能残留
——这时输出会多出奇怪的回车,看起来像行被覆盖。验证方法:打印每行长度,若比预期多 1,大概率是
没清理干净。
- 确认输入流未设
std::ios::binary - 不要对
std::getline结果再做line.erase(line.find_last_not_of(" ") + 1)这类操作——画蛇添足 - 跨平台调试时,可用
std::cout 查看末尾字节
一次性读整个字符串再分割,容易踩内存和性能坑
有人喜欢先用 std::stringstream 或 std::regex 把整个文本按
拆开,这在小文本上没问题,但遇到几百 MB 日志文件就可能爆内存,或因正则编译/匹配拖慢启动。
更隐蔽的问题是:不同平台换行符不统一,std::regex 写 "\n" 会漏掉
;而手写循环找
又得自己处理
和 EOF 边界。
- 坚持逐行读取,流式处理,内存占用恒定
- 若必须预加载(如 mmap 场景),用
std::string_view配合find+substr切分,避免拷贝 - 别用
boost::split或第三方库增加依赖——标准库够用
std::getline 返回值,导致最后一行读失败却仍参与输出;或者把输入重定向到文件时,没加 while (std::getline(std::cin, line)) 而是硬写固定循环次数。


















