2015-12-27 2 views
3

Мне нужно сделать программу на C++ в Linux, в которой используемые будут иметь возможность вводить целые числа, а не символы и специальные символы. Хорошо для окон (где я использовал заголовочный файл conio.h для getch()) ниже - программа, которая отлично работает.C++-программа для принятия только целых чисел от пользователя с использованием <curses.h> на Linux

#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> enter image description here

2> enter image description here

3> enter image description here

Во втором изображении, когда я нажимаю s, a и d, то эти символы также отображается, и я не хочу, чтобы это отображалось.

+0

Почему вы используете 'Геч()' на всех? – alk

+0

@alk, чтобы при вводе символа он не будет отображаться на экране. –

+0

Избегайте использования [* magic numbers *] (https://en.wikipedia.org/wiki/Magic_number_%28programming%29) как можно больше. Для [классификации символов] (http://en.cppreference.com/w/cpp/string/byte#Character_classification) используйте существующие функции, такие как ['std :: isdigit'] (http://en.cppreference.com/w/CPP/строка/байт/isdigit). Во всех других местах вместо этого используются фактические буквенные символы. '' \ n'' вместо '13'. Это сделает код более понятным и понятным для чтения, как для других, так и для себя через несколько месяцев. –

ответ

1

Если вы настаиваете на смешивание iostream и ругательства, есть оставшиеся несколько проблем, исправленных в этом модифицированном пример:

  • initscr устанавливает флаг, прописывающий проклятия, чтобы очистить экран при следующем обновлении. getch освежает экран.
  • Цель OP заключается не в предоставлении полноэкранной программы; использовать filter для одной строки подсказки
  • только в случае, если завалялись некоторый выход с помощью проклятий, используйте newterm, чтобы сделать выход проклятий перейти к стандартной ошибке (что позволяет один перенаправлять вывод программы)
  • endwin возвращает - 1 при ошибке, что, вероятно, не является намерением вернуть код выхода из основного.

Вот пересмотренный пример:

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

Вам необходимо найти справочную страницу для isalpha, которая содержит записи для isdigit, isdigit_l и других. Код, который у вас есть, действительно ужасен и не имеет возможности работать в любой среде, в которой используются символы не-ascii (например, среда utf-8).

+0

Код был отредактирован по вашему запросу, и проблема остается. Я поставлю некоторые изображения консоли. Пожалуйста, подождите :) –

+0

Этот ответ больше похож на комментарий. –

1

Вам нужно будет сделать, по крайней мере, эти три вещи, чтобы получить код правильно работать, отмеченные с комментариями ниже:

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::, даже если он будет повторяться, он будет многократно «растрачивать» время, когда он поможет вам избежать таинственной ошибки.

ссылка как возможные отправные точки для просмотра документации:

Смежные вопросы