为什么getch不便携?

时间:2016-04-12 19:13:10

标签: c

是什么让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不是标准的”。

1 个答案:

答案 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中与其他平台上的终端配合使用的不同模型。