Мне нужно сделать программу на С ++ для Linux, в которой используемые будут иметь возможность вводить только целые числа, а не символы и специальные символы.
Хорошо для окон (где я использовал conio.h
заголовочный файл для getch()
) ниже находится программа, которая отлично работает.
#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()
без отображения на экране. Таким образом, основная цель этой программы состоит в том, чтобы показывать только число на выходе, а также на входе.
Вот некоторые изображения экранов:
Во втором изображении, когда я нажимаю s
, a
а также d
затем эти символы также отображаются, и я не хочу, чтобы это отображалось.
Если вы настаиваете на смешивании iostream и curses, остается несколько проблем, исправленных в этом модифицированном примере:
Вот пересмотренный пример:
#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;
}
Вам нужно будет сделать по крайней мере эти три вещи, чтобы ваш код работал правильно, отмеченные комментариями ниже:
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;
}
Как примечание, я бы посоветовал против using namespace std;
даже в файле .cpp, как в целом, так и особенно, когда вы включаете дополнительные библиотеки, как здесь. Просто слишком легко иметь конфликты имен и казаться необъяснимым странным поведением. Лучше напиши это std::
даже если он кажется повторяющимся, он сэкономит «потерянное» время много раз, когда поможет избежать таинственной ошибки.
Ссылки как возможные отправные точки для просмотра документации:
Вам нужно взглянуть на справочную страницу для isalpha
, который включает в себя записи для isdigit
, isdigit_l
и другие.
Код, который у вас есть, действительно ужасен и не имеет шансов работать в любой среде, в которой используются символы, отличные от ascii (например, в среде utf-8).