这是因为您的终端输入缓冲在内核的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