這是因爲您的終端輸入緩衝在內核的I/O queue中。
終端設備的輸入和輸出隊列在內核中執行緩衝形式,而不依賴於由I/O流實現的緩衝。
終端輸入隊列有時也被稱爲其typeahead緩衝區。它保存已從終端接收但尚未被任何進程讀取的字符。
輸入隊列的大小由MAX_INPUT和_POSIX_MAX_INPUT參數描述;
默認情況下,您的終端在Canonical mode。
在規範模式下,所有輸入都保留在隊列中,直到接收到換行符爲止,因此當輸入一個很長的行時,終端輸入隊列可能會填滿。
現在回答你的問題:
有沒有一種方法來指示scanf
閱讀比2線嗎?
2行概念錯誤。無論如何,如果終端的I/O隊列的最大大小設置爲4096字節,則不能指示scanf
讀取多於4096個字節。
是否還有其他我們可以使用的功能沒有這個限制?
不,你甚至不能使用任何其他功能。這不是scanf
的限制。
編輯:發現這樣做
我們可以從canonical mode改變終端的輸入模式non-canonical mode.
要改變,我們必須使用low level terminal interface輸入模式的一個相當標準的方式。
我們可以做任務如下:
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
int clear_icanon(void)
{
struct termios settings;
int result;
result = tcgetattr (STDIN_FILENO, &settings);
if (result < 0)
{
perror ("error in tcgetattr");
return 0;
}
settings.c_lflag &= ~ICANON;
result = tcsetattr (STDIN_FILENO, TCSANOW, &settings);
if (result < 0)
{
perror ("error in tcsetattr");
return 0;
}
return 1;
}
int main()
{
clear_icanon(); // Changes the input mode of terminal from canonical mode to non canonical mode.
char input_array[5000];
int len;
printf("Enter key: ");
scanf("%s",input_array);
len = strlen(input_array);
printf("Message: %s\n",input_array);
printf("Message Len: %d\n",len);
return 0;
}
如果你想知道如何從終端
$ stty -icanon (changes the input mode to non-canonical)
$ stty icanon (changes it back to canonical)
早些時候的答案是做到這一點:(此技術是older)
我不知道whe這是最好的方式,但它可以通過將終端模式從cooked
(默認)更改爲cbreak
或raw
模式來完成。
當終端處於cbreak
模式時,它一次只能處理單個字符,而不是強制等待整行,然後一次輸入所有行。
在執行程序之前,您可以在終端中使用stty cbreak
。
或
要使用CBREAK模式編程
首先通過運行
$ sudo apt-get install libncurses5-dev
下一頁編輯程序安裝curses
包如下:
#include <stdio.h>
#include <string.h>
#include <curses.h>
int main()
{
initscr(); //start curses mode
cbreak(); //change the terminal mode to cbreak. Can also use raw();
endwin(); //end curses mode
char input_array[5000];
int len;
printf("Enter key:");
scanf("%s",input_array);
len = strlen(input_array);
printf("Message:%s\n",input_array);
printf("Message Len:%d\n",len);
return 0;
}
現在與編譯-lcurses
選項
$ gcc 1.c -lcurses
'scanf'停在第一個空白處,''\ n'',''\ t''和''''被認爲是空格,您可以使用'fgets'並去掉尾隨換行符。 –
C11草案標準n1570:* 7.21.6.2 fscanf函數12 轉換說明符及其含義如下:[...] s 匹配一系列非空白字符[...] * – EOF
@AlterMann我們從字符串中刪除了所有新行。我使用dd來生成大字符串。例如'dd if = <(yes hi | tr -d'\ n')bs = 4100 count = 1' – AnkurTank