另外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的值。不要試圖做到這一點。 –