C ++ символ для int - PullRequest
       66

C ++ символ для int

9 голосов
/ 09 марта 2010

что происходит, когда вы помещаете cin >> в переменную int? Я попробовал простой код, чтобы добавить 2 числа int, сначала прочитайте их, а затем добавьте их. Но когда я ввожу букву, она просто выходит из строя и выводит на экран тонны цифр. Но что вызывает эту ошибку? Я имею в виду, я ожидал, что он загрузит и использует ASCII-код этой буквы.

Ответы [ 5 ]

10 голосов
/ 09 марта 2010

Полагаю, у вас есть такой код:

int n;
while (someCondition) {
    std::cin >> n;
    .....
    std::cout << someOutput;
}

Когда вы вводите что-то, что не может быть прочитано как целое число, поток (std :: cin) переходит в состояние сбоя, и все последующие попытки ввода терпят неудачу, если вы не имеете дело с ошибкой ввода.

Вы можете проверить успешность операции ввода:

if (!(std::cin >> n)) //failed to read int

и вы можете восстановить поток в хорошем состоянии и отбросить необработанные символы (ввод, вызвавший сбой ввода):

std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

Другая возможность - принять ввод в строковую переменную (которая редко дает сбой) и попытаться преобразовать строку в int.

Это очень распространенная проблема с вводом, и здесь и в других местах должно быть множество тем.

3 голосов
/ 09 марта 2010

если вы явно приведете свой символ к типу int, он будет использовать код ASCII, иначе он сам не будет приводить тип к int, поэтому вы получите странные результаты, которые вы получаете.

1 голос
/ 09 марта 2010

Когда вы делаете что-то вроде:

int x;
cin >> x;

Вы указываете C ++ ожидать чтения int с клавиатуры. На самом деле, когда вы вводите что-то, отличное от int, поток ввода (в данном случае стандартный ввод) становится непригодным из-за состояния ошибки.

Вот почему я лично предпочитаю всегда читать строки и при необходимости конвертировать их в числа. В части C стандартной библиотеки C ++ есть функции преобразования, которые могут помочь с этим.

double cnvtToNumber(const std::string &num)
{
    char * ptr;
    double toret = strtod( num.c_str(), &ptr );

    if ( *ptr != 0 ) { // If it got to the end of the string, then it is correct.
        throw std::runtime_error( "input was not a number" );
    }
    return toret;
}

Здесь вы конвертируете число и определяете, было ли преобразование правильным. strtod(s) остановится только при нахождении конца строки или пробела. Чтобы избежать запаздывающих пробелов в функции, вам может понадобиться функция обрезки:

std::string &trim(std::string &str)
{
    // Remove trailing spaces
    unsigned int pos = str.length() -1;

    while( str[ pos ] == ' ' ) {
        --pos;
    }

    if ( pos < ( str.length() -1 ) ) {
        str.erase( pos + 1 );
    }

    // Remove spaces at the beginning
    pos = 0;
    while( str[ pos ] == ' ' ) {
        ++pos;
    }

    if ( pos < 1 ) {
        str.erase( 0, pos );
    }

    return str;
}

Теперь вы можете безопасно читать с консоли (или любого другого входного потока):

int main()
{
    std::string entry;

    try {
        std::getline( std::cin, entry );
        int age = cnvtToNumber( trim( entry ) );

        std::cout << age << std::endl;
    } catch(const std::exception &e) {
        std::cerr << e.what() << std::endl;
    }
}

Конечно, вы можете потерять точность, если будете всегда читать double и затем конвертировать их. Существуют специальные функции для целых чисел (strtol(s)), на случай, если вы захотите продолжить исследование.

1 голос
/ 09 марта 2010

Проблема заключается в том, что при чтении в целочисленную переменную с использованием потоков C ++ метод ввода ожидает символы, которые могут составлять число, например '+', '-', '0' ... '9' , Любой символ, который не входит в этот набор, завершает ввод, и из этих символов создается число.

Чтобы получить значение ASCII символа, вам нужно ввести данные в переменную char. Внутренне он имеет значение ASCII (при условии, что программа не читает 16-битные символы или EBCDIC). Если вы хотите увидеть значение ASCII, вам нужно вывести переменную char в виде целого числа (обычно требующего преобразования перед выводом).

Если не удается прочитать целое число, ваша программа должна сообщить пользователю, что ввод был неверным. Программа может потребовать от пользователя ввода номера еще раз, прежде чем программа сможет обработать введенные данные.

1 голос
/ 09 марта 2010

Вы можете использовать int istream::get();

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...