为什么 getchar 像缓冲区一样工作,而不是像预期的那样实时工作
Why does getchar work like a buffer instead of working as expected in real-time
这是我关于 Whosebug 的第一个问题。如果我没有正确搜索,请原谅我,但我似乎找不到对此的解释。只是尝试从 Bjourne Stroustroup 的论文中举一个例子。添加了我的位以查看数组在我键入文本时重新调整大小。
但好像不是这样的! getchar() 只是等到我输入完所有字符,然后它会执行循环。按照逻辑,它实际上并没有进入循环,获取一个角色,执行它的动作然后迭代。我想知道这是特定于实现的还是打算像这样?
我在 Ubuntu 14.04 LTS 上使用 Codeblocks 和 gcc 4.8.2。如果重要的话,源代码在 cpp 文件中。
while(true)
{
int c = getchar();
if(c=='\n' || c==EOF)
{
text[i] = 0;
break;
}
text[i] = c;
if(i == maxsize-1)
{
maxsize = maxsize+maxsize;
text = (char*)realloc(text,maxsize);
if(text == 0) exit(1);
cout << "\n Increasing array size to " << maxsize << endl;
}
i++;
}
输出结果如下:
数组大小现在是:10
请输入一些文本:这是一些示例文本。我希望看到内存在这里被重新分配,但显然它不是这样工作的!
将数组大小增加到 20
将数组大小增加到 40
将数组大小增加到 80
将数组大小增加到 160
您输入了:这是一些示例文本。我希望看到内存在这里被重新分配,但显然它不是这样工作的!
数组大小现在是:160
这与getchar
没有直接关系。 "problem" 是底层终端,它将缓冲您的输入。按下回车键后,输入将发送到程序。在 Linux 中(不知道 Windows 中是否有办法)你可以通过调用
来解决这个问题
/bin/stty raw
在终端中或通过调用
system ("/bin/stty raw");
在你的程序中。这将导致 getchar 立即 return 将输入的字符提供给您。
不要忘记通过调用
重置 tty
行为
/bin/stty cooked
完成后!
这是一个例子(Linux):
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main() {
system ("/bin/stty raw");
char c = getchar();
system ("/bin/stty cooked");
return 0;
}
也看看这个 SO Post:How to avoid press enter with any getchar()
此外,正如评论中所建议的,请看这里:http://linux.die.net/man/3/termios 尤其是命令 tcsetattr
,它应该可以跨平台工作。
实际上,tcsetattr
不适用于 Windows(即本网站中通常所说的 "cross-platform")。但是,问题被标记为 Linux,因此 "cross-platform" 是一个有争议的问题。
默认情况下,标准输入、输出和错误流设置为
- 行缓冲(输入)
- 块缓冲(输出)
- 行缓冲(错误)
您可以更改 that 使用 setbuf
, but of course will not solve the problem (the answer calls for single-character input). POSIX terminal I/O (termios) 允许您通过系统调用更改使用 stty
显示的任何标志。通常,您可以直接从脚本调用 stty
,很少从 C 程序调用。
读取单个字符是一个常见问题,例如
- How can I read single characters from the terminal? (unix-faq)
- How can I read a single character from the keyboard without waiting for the RETURN key? How can I stop characters from being echoed on the screen as they're typed?(comp.lang.c 常见问题解答)
您也可以使用 ncurses: filter
function is useful for programs that process a command-line (rather than a full-screen application). There is a sample program in ncurses-examples
(filter.c) 来执行此操作。
这是我关于 Whosebug 的第一个问题。如果我没有正确搜索,请原谅我,但我似乎找不到对此的解释。只是尝试从 Bjourne Stroustroup 的论文中举一个例子。添加了我的位以查看数组在我键入文本时重新调整大小。
但好像不是这样的! getchar() 只是等到我输入完所有字符,然后它会执行循环。按照逻辑,它实际上并没有进入循环,获取一个角色,执行它的动作然后迭代。我想知道这是特定于实现的还是打算像这样?
我在 Ubuntu 14.04 LTS 上使用 Codeblocks 和 gcc 4.8.2。如果重要的话,源代码在 cpp 文件中。
while(true)
{
int c = getchar();
if(c=='\n' || c==EOF)
{
text[i] = 0;
break;
}
text[i] = c;
if(i == maxsize-1)
{
maxsize = maxsize+maxsize;
text = (char*)realloc(text,maxsize);
if(text == 0) exit(1);
cout << "\n Increasing array size to " << maxsize << endl;
}
i++;
}
输出结果如下:
数组大小现在是:10 请输入一些文本:这是一些示例文本。我希望看到内存在这里被重新分配,但显然它不是这样工作的!
将数组大小增加到 20
将数组大小增加到 40
将数组大小增加到 80
将数组大小增加到 160
您输入了:这是一些示例文本。我希望看到内存在这里被重新分配,但显然它不是这样工作的!
数组大小现在是:160
这与getchar
没有直接关系。 "problem" 是底层终端,它将缓冲您的输入。按下回车键后,输入将发送到程序。在 Linux 中(不知道 Windows 中是否有办法)你可以通过调用
/bin/stty raw
在终端中或通过调用
system ("/bin/stty raw");
在你的程序中。这将导致 getchar 立即 return 将输入的字符提供给您。
不要忘记通过调用
重置tty
行为
/bin/stty cooked
完成后!
这是一个例子(Linux):
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main() {
system ("/bin/stty raw");
char c = getchar();
system ("/bin/stty cooked");
return 0;
}
也看看这个 SO Post:How to avoid press enter with any getchar()
此外,正如评论中所建议的,请看这里:http://linux.die.net/man/3/termios 尤其是命令 tcsetattr
,它应该可以跨平台工作。
实际上,tcsetattr
不适用于 Windows(即本网站中通常所说的 "cross-platform")。但是,问题被标记为 Linux,因此 "cross-platform" 是一个有争议的问题。
默认情况下,标准输入、输出和错误流设置为
- 行缓冲(输入)
- 块缓冲(输出)
- 行缓冲(错误)
您可以更改 that 使用 setbuf
, but of course will not solve the problem (the answer calls for single-character input). POSIX terminal I/O (termios) 允许您通过系统调用更改使用 stty
显示的任何标志。通常,您可以直接从脚本调用 stty
,很少从 C 程序调用。
读取单个字符是一个常见问题,例如
- How can I read single characters from the terminal? (unix-faq)
- How can I read a single character from the keyboard without waiting for the RETURN key? How can I stop characters from being echoed on the screen as they're typed?(comp.lang.c 常见问题解答)
您也可以使用 ncurses: filter
function is useful for programs that process a command-line (rather than a full-screen application). There is a sample program in ncurses-examples
(filter.c) 来执行此操作。