核心思路是将每行存入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<: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 <h3>用 stack 实现自然的 LIFO 存储</h3>
<p>如果只关心“最后输入的最先输出”,<code>std::stack</code> 比 vector 更语义清晰,且 push/pop 操作天然适配该逻辑。</p>
<ul>
<li>每读一行就 <code>push</code> 进栈,读完后反复 <code>top()</code> + <code>pop()</code> 直到 <code>empty()</code>
</li>
<li>注意 <code>std::stack</code> 默认底层容器是 <code>std::deque</code>,若需高性能且数据量大,可显式指定 <code>std::vector</code>: <code>std::stack<:string std::vector>></:string></code>
</li>
<li>不要在循环中对空栈调用 <code>top()</code>,必须先检查 <code>!s.empty()</code>
</li>
</ul>
<pre class="brush:php;toolbar:false;">std::stack<:string> s;
std::string line;
while (std::getline(std::cin, line)) {
s.push(line);
}
while (!s.empty()) {
std::cout <h3>处理空行和结尾换行的细节</h3>
<p>实际输入常含空行,而 <code>std::getline</code> 会把空行读作长度为 0 的 <code>std::string</code>,这本身没问题;但输出时是否保留空行、末尾是否多打一个换行,容易被忽略。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2823" title="C++14"><img
src="https://img.php.cn/upload/manual/001/431/639/6ac8b33c327c4749.png" alt="C++14" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="overflowclass">C++14</a>
<p class="overflowclass">C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<ul>
<li>
<code>std::getline</code> 不保留行尾的 <code>\n</code>,所以每行输出需显式加 <code>'\n'</code>;否则所有内容会挤在一行</li>
<li>若原始输入以空行结尾,<code>getline</code> 仍会成功读入一个空字符串,它会被正常压栈或存入 vector —— 这是符合预期的行为</li>
<li>不建议用 <code>std::cout 替代 <code>'\n'</code>,前者强制 flush,影响性能且可能干扰重定向输出</code>
</li>
</ul>
<h3>超大文件下的内存与性能权衡</h3>
<p>当输入行数极多(如百万行以上),全量加载到内存可能 OOM。此时无法真正“反向输出”,只能退化为两遍扫描:第一遍统计行数并记录每行起始偏移(需 fseek 支持),第二遍从文件末尾向前解析行边界。</p>
<ul>
<li>标准 C++ iostream 不支持反向读取文本行,<code>std::ifstream</code> 没有 <code>seekg</code> 到某行开头的内置方法</li>
<li>可行替代方案:用 <code>mmap</code>(POSIX)或 <code>CreateFileMapping</code>(Windows)将文件映射进内存,然后从末尾向前扫描 <code>\n</code> 字符定位行首</li>
<li>更务实的做法是确认需求本质——是否真需要“严格按输入顺序逆序”,还是仅需“倒序处理流式数据”?后者可用外部排序或分块处理</li>
</ul>
<p>多数实际场景(命令行工具、OJ 题目、日志预处理)用 vector 或 stack 就够了;真遇到 GB 级文本,得先问清楚“为什么必须反向输出”,而不是硬套通用解法。</p></:string>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










