【问题标题】:Why writing to standard input works?为什么写入标准输入有效?
【发布时间】:2015-11-19 15:22:21
【问题描述】:

我写到标准输入,它出现在屏幕上(0个标准输入,1个标准输出,2个标准错误

const int SIZE=12;

int main()
{
    int fd = open("input.txt", O_RDWR);
    char buffer[SIZE] = "Hello world";
    write(fd, buffer, SIZE - 1);

    lseek(fd, 0, SEEK_SET);
    char mem[SIZE];
    read(fd, mem, SIZE - 1);
    mem[SIZE] = '\0';

    write(0, mem, SIZE - 1);
    printf("\n");
    write(1, mem, SIZE - 1);
    printf("\n");
    write(2, mem, SIZE - 1);
    printf("\n");

    return 0;
}

输出:

Hello world
Hello world
Hello world

这是如何工作的?标准输入不连接键盘吗?

谢谢。

【问题讨论】:

  • 一旦你有未定义的行为,无论发生什么,无论多么难以置信,都是允许的。

标签: c++ operating-system file-descriptor system-calls redirectstandardoutput


【解决方案1】:

我无法在 Windows 7 上使用 Cygwin 重新创建。 这是我的程序:

#include <cstdio>

int main(void)
{
    static const char   text_hello[] = "Hello fwrite to stdin.\n";
    fprintf(stdin, "This is from stdin.\n");
    fwrite(text_hello, 1, sizeof(text_hello) - 1, stdin);

    return 0;
}

使用 g++ 版本 4.9.2。 我没有在控制台窗口上显示任何内容。

【讨论】:

  • 是的,但是通过写入(系统调用,而不是库函数)输出。
【解决方案2】:

stdinstdout 经常——至少在 Linux 系统上——指的是文件系统中的同一个实体,一个单独的设备文件,比如/dev/tty2。这些“文件”由特定驱动程序生成,该驱动程序会收到有关该文件的任何操作的通知。

当您从中读取时,驱动程序会访问(以某种方式,可能通过多个其他驱动程序)您坐在前面的键盘,并返回您键入的任何内容(由中间的软件层过滤)作为文件。

当你在写的时候,驱动程序知道它需要采取不同的行动,并通过驱动程序/显示服务器/终端模拟器的软件堆栈引导你的数据,最终将它显示给你。

因此,当您写入stdin 时,驱动程序所看到的只是您写入其设备文件,这意味着它应该显示您写入的内容。


也就是说这绝对不是一种可移植的行为,所以不要指望这会发生在不同的平台上。

【讨论】:

    【解决方案3】:

    UNIX 机器最初有控制台,通常通过串行电缆连接。就操作系统而言,远程屏幕和键盘是一个设备,即“控制台”,通过单个链接连接。

    这种设计仍然反映在几乎所有操作系统中。想象一下,如果它以不同的方式工作,那将是多么疯狂。假设您运行两个 Windows 控制台应用程序。他们应该共享相同的键盘和屏幕连接吗?或者他们应该有自己的控制台窗口,有一个逻辑输入流和一个逻辑输出流?

    当您按键盘上的退格键纠正错误时,应该备份键盘 还是屏幕?它们必须是相同的设备。

    【讨论】:

    • 能否请您寄一些纸或其他我可以阅读的东西。这有点令人困惑,为什么区分输入和输出是只有一个设备用于操作系统?
    • @GrigorApoyan 有很多设备。 Windows 机器可以有多个文本控制台窗口,每个窗口都有一个输入和输出流。一台 UNIX 机器可以有一个或多个本地控制台、通过网络连接的人员、由软件模拟的虚拟控制台等等。
    【解决方案4】:

    在我看来,一旦你有了 fd,你就可以用它做任何你想做的事情。 stdin、stdout 和 stderr 是在 stdio.h 中声明的 const 指针,因此您无需手动打开它们,但您可以“滥用”它们并写入其中一个并从另一个读取。

    确实,有些系统标准输入直接连接到键盘,如下所述:http://www.cplusplus.com/reference/cstdio/stdin/

    更多信息:http://pubs.opengroup.org/onlinepubs/009695399/functions/stdin.html

    【讨论】:

    • 确实如此,但为什么写入标准输入会进入屏幕?不连接键盘吗?
    • 我编辑了一个补充。有些系统的标准输入不直接连接到键盘。我假设这也是你的情况
    • 这不合逻辑。我不敢相信,当我的程序想要从标准输入中读取内容时,它会从我的屏幕中读取内容:) 它应该连接到键盘或某些输入设备,而不是输出。
    • 我引用另一个问题:文件描述符 0、1 和 2 很可能都对读写都是开放的(实际上它们都指的是相同的底层“开放文件描述”),在这种情况下,您所做的将起作用。但据我所知,没有保证,所以它也可能不起作用。我确实相信 POSIX 在某处指定如果在 shell 调用程序时将 stderr 连接到终端,它应该是可读可写的,但我无法立即找到引用..
    猜你喜欢
    • 2013-11-06
    • 2012-01-01
    • 1970-01-01
    • 2020-08-04
    • 2019-11-22
    • 2012-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多