核心思路是将每行存入std::vector后倒序遍历输出:用std::getline逐行读入避免截断,while(std::getline(std::cin,line))判断EOF,再for(int i=lines.size()-1;i>=0;--i)安全逆序打印。

读取全部行后逆序遍历输出
核心思路是把每行存进 std::vector<:string></:string>,再倒着遍历打印。这是最直接、不易出错的做法,适用于内存可容纳全部输入的场景。
- 用
std::getline逐行读入,避免operator>>遇空格截断 - 注意判断
std::cin是否已到 EOF(比如用户 Ctrl+D 或文件结束),推荐用while (std::getline(std::cin, line))而非先cin.peek() == EOF - 反向遍历时用
for (int i = lines.size() - 1; i >= 0; --i),别写成i > -1——无符号类型下会溢出成极大值
std::vector<std::string> lines;
std::string line;
while (std::getline(std::cin, line)) {
lines.push_back(line);
}
for (int i = lines.size() - 1; i >= 0; --i) {
std::cout << lines[i] << '\n';
}用 stack 实现自然的 LIFO 存储
如果只关心“最后输入的最先输出”,std::stack 比 vector 更语义清晰,且 push/pop 操作天然适配该逻辑。
- 每读一行就
push进栈,读完后反复top()+pop()直到empty() - 注意
std::stack默认底层容器是std::deque,若需高性能且数据量大,可显式指定std::vector:std::stack<std::string, std::vector<std::string>> - 不要在循环中对空栈调用
top(),必须先检查!s.empty()
std::stack<std::string> s;
std::string line;
while (std::getline(std::cin, line)) {
s.push(line);
}
while (!s.empty()) {
std::cout << s.top() << '\n';
s.pop();
}处理空行和结尾换行的细节
实际输入常含空行,而 std::getline 会把空行读作长度为 0 的 std::string,这本身没问题;但输出时是否保留空行、末尾是否多打一个换行,容易被忽略。
-
std::getline不保留行尾的\n,所以每行输出需显式加'\n';否则所有内容会挤在一行 - 若原始输入以空行结尾,
getline仍会成功读入一个空字符串,它会被正常压栈或存入 vector —— 这是符合预期的行为 - 不建议用
std::cout << std::endl替代'\n',前者强制 flush,影响性能且可能干扰重定向输出
超大文件下的内存与性能权衡
当输入行数极多(如百万行以上),全量加载到内存可能 OOM。此时无法真正“反向输出”,只能退化为两遍扫描:第一遍统计行数并记录每行起始偏移(需 fseek 支持),第二遍从文件末尾向前解析行边界。
立即学习“C++免费学习笔记(深入)”;
- 标准 C++ iostream 不支持反向读取文本行,
std::ifstream没有seekg到某行开头的内置方法 - 可行替代方案:用
mmap(POSIX)或CreateFileMapping(Windows)将文件映射进内存,然后从末尾向前扫描\n字符定位行首 - 更务实的做法是确认需求本质——是否真需要“严格按输入顺序逆序”,还是仅需“倒序处理流式数据”?后者可用外部排序或分块处理
多数实际场景(命令行工具、OJ 题目、日志预处理)用 vector 或 stack 就够了;真遇到 GB 级文本,得先问清楚“为什么必须反向输出”,而不是硬套通用解法。


















