另外fprintf(stdin,
bug,你也忘了stdin
是不是键盘。最新的C11标准不知道键盘。在Linux图形桌面上,只有X11服务器正在从物理键盘读取数据。
实事求是地讲,在POSIX系统特别是如Linux,stdin
可以是pipe(7)(使用pipelines在你的shell是很常见的),一个fifo(7),一个socket(7),一个纯文本文件(直通redirection),甚至/dev/null
,和当然也是terminal。
有趣的,这些天是终端很经常的虚拟仿真设备(我没有看到任何真实的物理终端在本世纪,博物馆以外),了解pseudotty。由于历史原因,细节非常神秘。阅读tty demystified页面。另请参见ANSI escape code WIKIPAGE & console_codes(4)和tty(4)(所以考虑/dev/tty
也许/dev/console
)
您可以检查(带isatty(3))是标准输入是使用isatty(STDIN_FILENO)
终端(实际上是一个pseudotty)...
实际上讲,当你真的想要使用终端时,我强烈建议使用库如ncurses或GNU readline(均使用termios(3))
不要忘记I/O通常是buffered,并明智地使用fflush(3)。
顺便说一句,你应该编译所有警告&调试信息(gcc -Wall -Wextra -g
),然后使用gdb
调试器。而strace(1)也会非常有用。
也许你想管自己的程序(但是这很奇怪,而且往往是错误的,除非你非常关心所有的含义;然而这是一个在面向事件的程序中处理signal(7)非常有用的技巧,特别是那些与一些GUI)。请注意,管道的缓冲区大小有限(所以请避免使用deadlocks,可能是因为您的event loop使用了poll(2)),并阅读了大约PIPE_BUF
和write。你可能曾尝试:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
int pfd[2] = {-1,-1};
int a= 0;
if (pipe(pfd)) { perror("pipe"); exit (EXIT_FAILURE); };
if (dup2(pfd[0],STDIN_FILENO)<0)
{ perror("dup2 stdin"); exit(EXIT_FAILURE);};
if (dup2(pfd[1],STDOUT_FILENO)<0)
{ perror("dup2 stdout"); exit(EXIT_FAILURE);};
if (printf("%d\n", 123)<=0) { perror("printf"); exit(EXIT_FAILURE); };
if (fflush(stdout)) { perror("fflush"); exit(EXIT_FAILURE); };
if (scanf("%d", &a)<1) { perror("scanf"); exit(EXIT_FAILURE); };
if (a != 123) { fprintf(stderr, "impossible happened a=%d\n", a); };
fprintf(stderr, "done...got a=%d\n", a);
}
你应该阅读Advanced Linux Programming和了解syscalls(2);它有几个相关的章节。请仔细阅读pipe(2)和dup2(2)并意识到,上述方案将是错误的更大的输出(更大的是PIPE_BUF
,这在我的系统是几千字节)
BTW,您可以使用fmemopen(3)内存缓冲区得到一个可读FILE*
。对于写入(例如使用fprintf
)写入输出缓冲区,请考虑open_memstream
,并且在访问输出缓冲区之前不要忘记写入fflush
。
相关:http://stackoverflow.com/q/584868/694576 – alk
你到底想达到什么目的?如果你想使用“123”而不是stdin的输入,你应该写一个函数,在这种情况下返回“123”,否则返回stdin的值。不要试图做到这一点。 –