clrscr() not working, getch() working. Why?

白昼怎懂夜的黑 提交于 2019-11-28 11:00:10

问题


I'm making a small C program that asks for a key and executes some code in a switch statement.

#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() is working properly, but clrscr() is not, even if I included <conio.h>.

Why?


回答1:


conio.h is dead!

Some background: conio.h defines an API that was once created to control the (text!) screen of an IBM PC. It was originally just a wrapper around MS-DOS functions, so you didn't have to write your own assembly creating an int 21h to call them. The exact API of conio.h was never standardized and varies from implementation to implementation.

I assume you're using a compiler targeting Windows, these typically still provide some variation of conio.h. But as you can see, there's no guarantee what's really available and works as you would expect.

Nowadays, you'd even have to ask what is a screen? The content of your console window? But what if your controlling terminal is e.g. a remote shell (telnet, ssh, ...)? And even different console window implementations will differ in features and how you control them. C only knows input and output streams, they will work with any kind of terminal / console because they don't know anything about a screen, just input and output of characters.

For actually controlling the "screen", Windows provides the Console API, you could use that directly, but then your program is "hard-wired" to Windows only. Most other consoles / terminals understand some sort of escape codes, often the ANSI escape codes. Windows starting with Windows 10 has optional support for them as well. But there's a wide variety of terminals understanding different codes (and different subsets of them), so using them directly isn't a good idea either.


Nowadays, the de facto standard for controlling a terminal/console is the Curses API which has its roots in BSD Unix, but implementations exist for a large variety of systems and consoles. Most notably, ncurses is available for many systems, even including Windows, but for Windows, you also have pdcurses. There's even an extended pdcurses for Windows that implements its own console window, so you can use features the native Windows console doesn't have. Of course, you won't need this for just "clearing the screen" and reading some input from the keyboard.

When you use curses, you have to do all console/terminal input and output using curses functions (you can't use stdio functions like printf() for that). Here's a tiny example program:

#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
}

You can compile it e.g. with gcc like this for using ncurses:

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

Or with pdcurses:

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

To learn more about curses, I recommend the NCURSES Programming HOWTO.




回答2:


clrscr() is never part of any standards.Its a vendor specific functon provided by borland in conio.h(non standard). Try emulate its behavior by calling system("cls") , Include stdlib.h header file.




回答3:


I change your platform dependent function clrscr() and getch() to its correspondent standard system() and getchar().

Code

#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");
}

Compile

gcc t.c -o t

Its works fine on my machine.

Linux ss 4.8.0-36-generic

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



来源:https://stackoverflow.com/questions/45806357/clrscr-not-working-getch-working-why

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!