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

时间:2017-08-21 22:23:40

标签: c gcc conio

我正在制作一个小C程序,要求输入密钥并在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>

为什么?

3 个答案:

答案 0 :(得分:5)

conio.h已经死了!

一些背景知识:conio.h定义了曾经创建的API,用于控制IBM PC的(text!)屏幕。它最初只是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,因此您可以使用本机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
}

你可以编译它,例如使用gcc就可以使用ncurses

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

答案 1 :(得分:-1)

clrscr()永远不会成为任何标准的一部分。它是由borland在conio.h(非标准)中提供的供应商特定功能。 尝试通过调用system(&#34; cls&#34;),包含stdlib.h头文件来模拟其行为。

答案 2 :(得分:-2)

我将您的平台相关功能clrscr()getch()更改为其对应的标准system()getchar()

<强>代码

#include <stdio.h>
#include <stdlib.h>


int main(int argc, char const *argv[]){
    /* code */
    printf("Hello, press a, b or c to continue:\n");
    char key = getchar();
    printf("\n");

    switch (key){
    case  'a':
        system("clear");
        //some code
        break;
    case  'b':
        //many lines of code
        break;
    case  'c':
        system("clear");
        //many lines of code
        break;
    default:
        printf("Ok saliendo\n");
        break;
    }
    printf("bye\n");
}

<强>编译

gcc t.c -o t

它在我的机器上工作正常。

Linux ss 4.8.0-36-generic

gcc(Ubuntu 5.4.0-6ubuntu1~16.04.4)5.4.0 20160609