不能直接判断是否重定向,但可通过 isatty(fileno(stdin)) 检测 stdin 是否连接终端,从而间接判断——返回 true 表示未重定向(连终端),false 表示已重定向。

std::cin 的流状态能否反映重定向?
不能直接获取“是否被重定向”这个语义标志——C++ 标准库不提供 is_redirected() 这类接口。标准流(如 std::cin)只暴露底层文件描述符状态,不感知 shell 层的重定向行为。你真正能查的是:它当前绑定的文件描述符是否为终端(tty),这在绝大多数场景下可等价判断是否被重定向。
用 isatty() 检测 stdin 是否连到终端
isatty() 是最常用、最可靠的运行时判断方式,它检查文件描述符是否关联一个终端设备。对 std::cin,需先通过 fileno() 获取其底层 fd:
#include <unistd.h>
#include <iostream>
bool is_stdin_tty() {
return isatty(fileno(stdin)) != 0;
}
int main() {
if (is_stdin_tty()) {
std::cout
<ul>
<li>
<code>fileno(stdin)</code> 安全:C++ 标准保证 <code>stdin</code> 对应 <code>std::cin</code> 的底层 C FILE*</li>
<li>返回非零表示是 tty;返回 0 表示被重定向(含管道、文件、进程替换等)</li>
<li>注意:Windows 下需用 <code>_isatty()</code> 和 <code>_fileno()</code>,头文件为 <code><io.h></io.h></code>
</li>
</ul>
<h3>为什么不用 <code>std::cin.good()</code> 或 <code>std::cin.rdbuf()</code> 判断?</h3>
<p>这些方法容易误判:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill5502" title="C++ Code Review Master"><img
src="https://img.php.cn/upload/skill/000/000/081/179051228971575.jpg" alt="C++ Code Review Master" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill5502" title="C++ Code Review Master" class="overflowclass">C++ Code Review Master</a>
<p class="overflowclass">组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。</p>
</div>
<a rel="nofollow" href="/xiazai/skill5502" title="C++ Code Review Master" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<ul>
<li>
<code>std::cin.good()</code> 只反映流的错误/EOF 状态,和重定向无关;重定向后只要没出错,它仍是 <code>true</code>
</li>
<li>
<code>std::cin.rdbuf()</code> 返回的是 <code>std::streambuf*</code>,无法从中提取设备类型信息;自定义 buffer 更会让判断失效</li>
<li>试图读取一个字节再 <code>unget()</code> 来试探——不可靠,会干扰后续读取,且对管道可能阻塞</li>
</ul>
<h3>跨平台兼容与常见陷阱</h3>
<p>实际部署时要注意:</p>
<ul>
<li>Linux/macOS 用 <code>isatty(STDIN_FILENO)</code> 更直接,避免依赖 <code>stdin</code> 全局变量(某些嵌入式或沙箱环境可能被修改)</li>
<li>在 Docker 容器中,即使未显式重定向,<code>docker run -i</code> 仍可能让 <code>isatty()</code> 返回 false;若需交互式行为,得额外检查 <code>TERM</code> 环境变量或加 <code>-t</code>
</li>
<li>如果程序被 systemd 或 init 系统托管,<code>stdin</code> 可能被设为 <code>/dev/null</code>,此时 <code>isatty()</code> 返回 0,但并非用户主动重定向——业务逻辑需区分“无输入”和“批量输入”场景</li>
</ul>
<p>真正关键的不是“有没有重定向”,而是“输入源是否支持交互式操作”。<code>isatty()</code> 给出的是最接近的系统级信号,其余都得靠约定或额外元信息补充。</p></iostream></unistd.h>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










