C++ 程序只接受用户使用 Linux 上的 <curses.h> 的整数

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

我需要在Linux上制作一个c++程序,其中使用的只能输入整数,不能输入字符和特殊字符。 那么对于 windows(我在 getch() 中使用了 conio.h 头文件)下面是运行良好的程序。

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

现在 Linux 我使用 #include<curses.h> 头文件来使用 getch(); 代码是

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

在编译它时我得到一个新屏幕(我猜这可能是由于 initscr())并且每个数字、字符和特殊字符都打印在屏幕上,如果我按回车键,屏幕也会保留原样。

我需要做什么正确性?

为什么我使用 getch()?

因为 variable ch 将存储通过 getch() 输入的任何内容而不显示在屏幕上。所以这个程序的主要目的是只在输出和输入中显示数字。

以下是一些屏幕图像:-

1>

2>

3>

在第二张图片中,当我按下 sad 时,这些字符也会显示,但我不希望显示这些字符。

您需要查看 isalpha 的手册页,其中包括 isdigitisdigit_l 和其他条目。 你的代码真的很糟糕,在任何使用非 ascii 字符的环境(例如 utf-8 环境)中都无法工作。

你至少需要做这三件事才能让你的代码正常工作,下面用评论标记:

int getOnlyNumbers()
{
    int ch;
    int num = 0;
    initscr();
    // disable echo by calling noecho() function
    noecho();
    do
    {
        ch = getch();
        if(isdigit(ch))
        {
            // cast int to char to get correct printout,
            // and flush to force printing it without a newline.
            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);
    return num;
}

作为旁注,我建议即使在 .cpp 文件中也不要 using namespace std;,一般情况下,尤其是当您包含额外的库时,如此处。名称冲突和看似无法解释的奇怪行为太容易了。最好输入 std::,即使它感觉重复,它会帮助您避免神秘错误,从而节省 "wasted" 很多次时间。

链接作为浏览文档的可能起点:

如果您坚持将 iostream 和 curses 混合使用,则还存在一些问题,已在本修改示例中修复:

  • initscr sets a flag telling curses to clear the screen on the next refresh. getch 刷新屏幕。
  • OP的本意不是提供全屏程序;对单行提示使用 filter
  • 以防某些使用 curses 的输出被忽略,使用 newterm 使 curses 的输出转到标准错误(允许重定向程序的输出)
  • endwin returns 错误时为 -1,这可能不是从 main 返回退出代码的意图。

修改后的例子如下:

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