clrscr() 不工作,getch() 工作。为什么?

标签 c gcc conio

我正在做一个小C请求 key 并执行 switch 语句中的一些代码的程序。

#include <stdio.h>
#include <conio.h>

int main(int argc, char const *argv[]){
    /* code */
    printf("Hello, press a, b or c to continue");
    char key = getch();
    switch (key){
    case  'a':
        clrscr();
        //some code
        break;
    case  'b':
        //many lines of code
        break;
    case  'c':
        clrscr();
        //many lines of code
        break;
    default:
        printf("Ok saliendo\n");
        break;
    }
    printf("bye");
}

getch()工作正常,但是 clrscr()不是,即使我包括 <conio.h> .

为什么?

最佳答案

conio.h死了!

一些背景:conio.h 定义了一个 API,该 API 曾被创建用于控制 IBM PC 的(文本!)屏幕。它最初只是 MS-DOS 函数的包装器,因此您不必编写自己的程序集来创建 int 21h 来调用它们。 conio.h 的确切 API 从未标准化,并且因实现而异。

我假设您使用的是针对 Windows 的编译器,这些编译器通常仍提供 conio.h 的一些变体。但正如您所看到的,无法保证哪些内容真正可用并且按您的预期工作。

如今,您甚至不得不问什么是屏幕?控制台窗口的内容?但是,如果您的控制终端是例如,该怎么办?远程 shell(telnet、ssh...)?甚至不同的控制台窗口实现在功能和控制方式上也会有所不同。 C 只知道输入和输出,它们可以与任何类型的终端/控制台一起工作,因为它们不知道任何关于屏幕的信息,只知道字符的输入和输出。

为了实际控制“屏幕”,Windows 提供了 Console API ,您可以直接使用它,但是您的程序仅“硬连线”到 Windows。大多数其他控制台/终端都理解某种转义码,通常是 ANSI escape codes 。从 Windows 10 开始的 Windows 也提供了对它们的可选支持。但是有各种各样的终端可以理解不同的代码(及其不同的子集),因此直接使用它们也不是一个好主意。

<小时/>

如今,控制终端/控制台的事实上的标准Curses API它起源于 BSD Unix,但存在多种系统和控制台的实现。最值得注意的是,ncurses适用于许多系统,甚至包括 Windows,但对于 Windows,您还可以使用 pdcurses 。甚至还有一个extended pdcurses适用于实现自己的控制台窗口的 Windows,因此您可以使用 native Windows 控制台所没有的功能。当然,您不需要它只是为了“清除屏幕”并从键盘读取一些输入。

当您使用curses时,您必须使用curses函数来完成所有控制台/终端输入和输出(您不能使用stdio类似 printf() 的函数)。这是一个小示例程序:

#include <curses.h>
// don't include `ncurses.h` here, so this program works with 
// different curses implementations

#include <ctype.h>  // for `isalnum()`

int main(void)
{
    initscr();  // initialize curses, this also "clears" the screen
    cbreak();   // among other things, disable buffering
    noecho();   // disable "echo" of characters from input

    addstr("Hello, press a key!\n");  // output a constant string, like puts/fputs
    refresh();  // output might be buffered, this forces copy to "screen"

    int c;
    do
    {
        c = getch();        // read a single character from keyboard
    } while (!isalnum(c));  // ignore any input that's not alphanumeric

    printw("You entered '%c'.\n", c);  // formatted output, like printf

    addstr("press key to exit.\n");
    refresh();
    c = getch();

    endwin();   // exit curses
}

你可以编译它,例如像这样使用 ncurses 的 gcc:

gcc -std=c11 -Wall -Wextra -pedantic -ocursestest cursestest.c -lncurses

或者使用pdcurses:

gcc -std=c11 -Wall -Wextra -pedantic -ocursestest cursestest.c -lpdcurses

要了解有关 curses 的更多信息,我推荐 NCURSES Programming HOWTO .

关于clrscr() 不工作,getch() 工作。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57757135/

相关文章:

java - 专门从 java.library.path 加载 native 库

gcc - 从cygwin64编译32位代码

gcc - 尽管缺少共享库和关联符号,如何链接可执行文件?

c - 如何在codeblock,Windows(初学者)中使用conio.h,dos.h,io.h头文件编译c代码?

c++ - 如何在输入和输出过程中始终连续闪烁特定文本?

c - 未定义的 C 结构前向声明

c - 这段C代码如何原位反转二叉树?

c - 请求成员 "duree"不是 scanf 中整数的结构或 union

objective-c - 在 C 数组中存储 NSObject 指针数组

c - 使用 getch() 重复 key 检查的问题