Ввод Cin с + приводит к тому, что следующий ввод будет строкой - PullRequest
3 голосов
/ 04 марта 2020

так что я довольно новичок в C ++ и делаю задание для своего класса. Я столкнулся с проблемой при попытке проверить, является ли ввод строкой или double / int. Итак, я сделал базовую c программу для ее проверки

#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
    string hi;
    double hello;

    cin >> hello;

    if (!cin)
    {
        //Strings go here

        cin.clear();
        cin >> hi;
        cout << hi << endl;
    }
    else
    {
        cout << hello << endl;
    }

    cout << "Done!" << endl;
}

Так что она работает в основном при вводе буквы (например, "j" или "a") или числа, но при вводе "+" или "-" он ждет следующего ввода, а затем пропускает его через строковый блок, даже если это число. Однако "*" или "/" читаются как строки и не вызывают этой проблемы (я предполагаю, что они не являются явно операторами). Я предполагаю, что я, вероятно, что-то упустил. Спасибо


Редактировать: я тестирую по одному типу за раз (например, 123, 1, d, +) без типов смешения, поэтому не будет входов с двойным и строка

В соответствии с предложением пользователя 4581301 я приведу в некоторых примерах входы и выходы

Входы: Выходы

"Hello": "Hello"

123: 123

"/": "/"

"+" (ввод после: 2): "2"

1 Ответ

2 голосов
/ 05 марта 2020

Проблема

Ваша программа работает не совсем так, как задумано, поскольку она не учитывает потенциально потребляемые, но потерянные символы.

Вот различные случаи, которые работают как ожидалось:

  • abc: первое чтение символа не числовое c, поэтому оно не используется и cin быстро завершается неудачно. Во втором чтении все символы представлены в виде строки.
  • 123abc456: прочитано первое 123. Когда встречается a, он не расходуется, поскольку недопустим для чисел c. Дальнейшее чтение остановлено, но можно прочитать значение цифры c.
  • /123: первое чтение символа не цифра c, поэтому оно не используется и cin завершается ошибкой. второе чтение читает каждый символ, представленный в виде строки.
  • -123 или +123: первый символ считается действительным значением цифр c и читается, а затем читается остаток, по-прежнему как числовое значение c. Работает, как и ожидалось, если вы считаете, что двойное число или int может быть подписано. В зависимости от формата вывода значок + может не отображаться вместе с выводом.

Вот случаи, которые не работают: если первый символ равен + или -, но за ним не следует допустимая цифра c char. В этом случае первый символ используется, но следующий символ приводит к сбою ввода цифр c. Остальные символы затем читаются как строки (за исключением первого знака, который уже был использован и потерян). Примеры:

  • ++123
  • + 123 (пробел завершает извлечение двойного числа, которое не удалось, остаток читается как строка).

Онлайн-демонстрация

Решение

Самое простое решение - прочитать входные данные как строку, а затем попытаться преобразовать строку.

Например:

size_t processed;
string hi;
double hello;
cin >> hi;

try {
    hello = stod(hi,&processed); 
    cout<<"number:" <<hello; 
    if (processed<hi.size()) 
        cout << " (followed by something)";
    cout <<endl; 
}
catch (...)   // should be more precise in catching, but it's for the proof of concept 
{
    cout <<"string: "<< hi << endl;
}

Онлайн-демонстрация

Если вы хотите считать + и - как alphanumeri c, это будет Легко проверить, если hi не пусто и привет [0], а di git, прежде чем пытаться выполнить преобразование.

В качестве альтернативы, вы также можете выполнить проверку строки regex , чтобы увидеть, соответствует ли она формату цифры 1067 *.

...