Search code examples
c++linuxncursescurses

C++ program to accept only the integers from the user using <curses.h> on Linux


I need to make a c++ program on Linux in which the used will only be able to input integers and no characters and special characters. Well for windows (where I have used the conio.h header file for getch()) below is the program which works fine.

#include<iostream>
#include<stdio.h>
#include<conio.h>
 int getOnlyIntegers()
 {
    int ch;
    long int num = 0;
    do
    {
        ch = getch();
        if(ch >= 48 && ch <= 57)
        {
            printf("%c",ch);
            num = (ch-48) + (num*10);
        }
        if(ch == 13)
        {
            break;
        }
    }while(1);
    return num;
 }
 int main()
 {
    int x;
    x = getOnlyIntegers();
    printf("\n%d", x);
    return 0;
 }

Now in Linux I'm using #include<curses.h> header file for using getch(); and the code is

#include<iostream>
#include<ctype.h>
#include "curses.h"
using namespace std;
int getOnlyNumbers()
{
    int ch;
    int num = 0;
    initscr();
    do
    {
        ch = getch();
        if(isdigit(ch))
        {
            cout<<ch;
            num = (ch - 48) + (num*10);
        }
        if(ch == '\n') // if the user press enter key
        {
            break;
        }
    }while(1);
    return num;
}
int main()
{
    int num;
    num = getOnlyNumbers();
    cout<<endl<<num;
    return endwin();
}

on compiling it I get a new screen (I guess that is probably due to initscr()) and every number, character and special character is getting printed on screen and if I press enter then also the screen remains as it was.

What correctness I need to do?

why I used getch()?

because variable ch will store whatever is entered through getch() without being displayed on the screen. So the main purpose of this program is to only show number on output as well as in input.

Here are some images of the screens :-

1> enter image description here

2> enter image description here

3> enter image description here

In the second Image when I press s, a and d then these characters are also getting displayed and I don't want that to be displayed.


Solution

  • If you insist on mixing iostream and curses, there are a few problems remaining, fixed in this modified example:

    • initscr sets a flag telling curses to clear the screen on the next refresh. getch refreshes the screen.
    • OP's intent is not to provide a full-screen program; use filter for single-line prompts
    • just in case some output using curses was overlooked, use newterm to make curses' output go to the standard error (allowing one to redirect the output of the program)
    • endwin returns a -1 on error, which is probably not the intent for returning an exit-code from main.

    Here is the revised example:

    #include <iostream>
    #include <ctype.h>
    #include <curses.h>
    using namespace std;
    int getOnlyNumbers()
    {
        int ch;
        int num = 0;
        filter();
        newterm(NULL, stderr, stdin);
        noecho();
        do
        {
            ch = getch();
            if(isdigit(ch))
            {
                std::cout << static_cast<char>(ch) << std::flush; 
                num = (ch - 48) + (num*10);
            }
            if(ch == '\n') // if the user press enter key
            {
                break;
            }
        } while(1);
        endwin();
        return num;
    }
    int main()
    {
        int num;
        num = getOnlyNumbers();
        cout<<endl<<num;
        return 0;
    }