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>
在第二张图片中,当我按下 s
、a
和 d
时,这些字符也会显示,但我不希望显示这些字符。
您需要查看 isalpha
的手册页,其中包括 isdigit
、isdigit_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;
}
我需要在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>
在第二张图片中,当我按下 s
、a
和 d
时,这些字符也会显示,但我不希望显示这些字符。
您需要查看 isalpha
的手册页,其中包括 isdigit
、isdigit_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;
}