是什么让getch固有地不可移植成为标准C函数?
控制台界面非常直观和优雅。没有它,要求单个字符总是会产生误导,因为允许用户输入多个密钥。
更糟糕的是,在阅读控制台输入后,您经常需要确保清除标准输入,这甚至不作为标准功能提供!我必须自己使用!
一个简单的程序,可能是:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
int main(int argc, char **argv)
{
while (1) {
char yes_or_no;
printf("is this statement correct? 1 + 1 = 2(Y/N) $ ");
yes_or_no = tolower(getch());
switch (yes_or_no) {
case 'y':
puts("Right!");
goto done;
case 'n':
puts("\nhint> Please just say yes for the sake of this demo...");
break;
case 'q':
puts("\nExitting.");
goto done;
case EOF:
puts("\nEOF.");
goto done;
default:
printf("\nunknown response '%c'.\n", yes_or_no);
break;
}
}
done:
return 0;
}
变为:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
static inline void flush_stdin()
{
char ch;
do {
ch = getchar();
} while ((ch != '\n') && (ch != EOF));
}
int main(int argc, char **argv)
{
while (1) {
char yes_or_no;
printf("is this statement correct? 1 + 1 = 2(Y/N) $ ");
yes_or_no = tolower(getchar());
switch (yes_or_no) {
case 'y':
puts("Right!");
goto done;
case 'n':
puts("hint> Please just say yes for the sake of this demo...");
break;
case EOF:
puts("EOF.");
goto done;
default:
printf("unknown response '%c'.\n", yes_or_no);
break;
}
flush_stdin(); /* remove this to see the difference */
}
done:
return 0;
}
每次我想制作一个简单的便携式控制台程序时,我都会被迫制作这样的一系列功能,并且最终还没有得到我想要的所有东西,比如getch。
当然,你可以使用curses,但curses接管你的整个控制台,并使你的程序行为与普通用户期望的不同(程序只是滚动,并仍然显示你运行程序的命令)控制台缓冲区)。
我知道“为什么”是一个糟糕的问题(应该总是优先考虑),但必须要问。在桌面系统无法支持的getch中是否存在任何固有的不可移植性?如果没有,我可以自己编写并将其移植到我想支持的所有平台上,我很好。
如果桌面系统无法支持getch,那么它是什么?因此,我有更好的理由理解为什么避免使用conio而不是“只使用ncurses / conio不是标准的”。
答案 0 :(得分:5)
C标准没有终端或Windows的概念。与这些事情有关的任何事情都是特定于实现的,不能成为C编程语言的一部分。
但是,有终端编程的行业标准。一个是POSIX(IEEE 1003.1)的一部分作为 termios 终端驱动程序接口,一个是X / Open curses,它指定一个C函数库来操作更高级别的终端,第三个是ISO 6429 ,ANSI终端转义序列集。
顺便提一下,X / Open curses提供了getch()
函数。 Microsoft Windows也支持这些标准,但不是很有用。
在Windows上使用getch()
的方式(即通过conio.h
)是不可移植的,因为conio.h
是一个特定于DOS的标头,由于它不能在其他平台上轻松实现控制台在DOS中与其他平台上的终端配合使用的不同模型。