Почему моя программа получает ошибку во время выполнения, когда я выполняю свой код?

0

Эта программа работает без цикла, однако, когда я реализую цикл, я получаю ошибку времени выполнения. Я думаю, что это может иметь какое-то отношение к моей cin.getline, но я действительно понятия не имею:/любая помощь была бы большой благодаря вам!

#include <iostream>
using namespace std;
#include <string>
#include <iomanip>


int main ()
{int ans, z;
z=1;
cout << "How many times would you like to execute this string program? " << endl;
cin >> ans;
while (z <= ans)
{  
    int x, i, y, v;
    string answer1, str3;
    string mystring, fname, lname;


    i=0;
    y=0;

    cout << "Please enter your first and last name: ";
    getline(cin, answer1);
    cout << endl;

    x=answer1.length();
    for (int i = 0; i < x; i++)
    {
        cout << answer1[i] << endl;
        if (isspace(answer1[i])) 
        {
            y=i;
        }
    }

    cout << endl << endl;
    cout << setw(80) << answer1;

    mystring = answer1;

    v=answer1.find(" ", 0);

    fname=mystring.substr(0, y);
    lname=mystring.substr(v, x);
    cout << "First name: " << fname << endl;
    cout << "Last name: " << lname << endl;

    mystring=lname+','+fname;

    cout << setw(80) << mystring;
    z++;    

}

return 0;

}
  • 0
    Можете ли вы объяснить ошибку более подробно? Какую именно ошибку вы получаете?
  • 0
    Это приложение запросило среду выполнения прекратить его необычным способом. Пожалуйста, обратитесь в службу поддержки.
Показать ещё 3 комментария
Теги:
return

2 ответа

1

Ошибка в этой строке:

lname=mystring.substr(v, x);

где v имеет очень большое значение. Итак, как ваша программа попадает туда, и как v получает эту ценность? v имеет значение std::string::npos, что означает код ошибки, в данном случае, что место, которое вы искали, не было. Это связано с различием между форматированным и неформатированным вводом и тем фактом, что вы их смешиваете.

Форматированный вход означает обработку входного потока в виде потока токенов. Ведущие пробелы - пробелы, пробел, табуляция или новая строка - пропущены, а конец токена - вход. Одним из примеров форматированного ввода является

cin >> ans;

Для форматированного ввода все, что не соответствует его шаблону, выглядит одинаково. Будет ли std::istream::operator>>(int) встречать пробел, вкладку, новую строку, 'a' или " z', это только конец токена, и там он перестает читать. Например, если у вас есть

int x;
std::string s;
std::cin >> x >> s;

и подайте его на вход 123abc, тогда x будет иметь значение 123, а s будет "abc". Реально, это означает, что если пользователь отвечает

cin >> ans;

с номером и новой строкой, встреченный символ после номера - новой строки - остается в потоке.

Неформатированный вход, напротив, означает обработку входного потока как потока символов. Для неформатированных входных функций пробелы - это еще один символ, и если неформатированная функция ввода определяет для них особый смысл, он будет относиться к ним так же, как и любой другой символ. Примером неформатированного ввода является

getline(cin, answer1);

который является сокращением для

getline(cin, answer1, '\n'); // that is to say, the delimiter
                             // has a default value of '\n'

(просто для того, чтобы было ясно, что символ новой строки '\n' имеет особый смысл в этом случае). getline, используемый таким образом, будет считывать из потока до тех пор, пока он не встретит новую строку.

И в этом твоя проблема. После предыдущей форматированной функции ввода в потоке остается материал, который вам неинтересен. Вероятно, это просто 123abc (хотя, если пользователь предоставил 123abc, он будет abc\n), и в этом случае getline даст вам пустую строку - там есть пустая строка в потоке, так что же еще она может сделать?

Существует несколько способов справиться с этим условием. Одно можно сказать

#include <iostream>
#include <limits>

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

Это, по существу, означает: игнорировать все до следующей новой строки (numeric_limits<streamsize>::max() - очень большое число, которое cin.ignore рассматривает как бесконечность). Другой

cin >> ws;

в котором говорится: "игнорировать все до следующего символа без пробелов", хотя это игнорирует ведущие пробелы в следующей строке и не будет игнорировать abc если пользователь предоставил 123abc. В вашем случае я считаю, что нет причин менять передачи с форматированного ввода - вам не нужна строка, но имена и фамилии. Я предлагаю использовать

string fname, lname;
cin >> fname >> lname;

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

0

Делать

cin >> ans;
cin >> std::ws;

перед циклом while. Кроме того, проверьте

v=answer1.find(" ", 0);

для std :: npos

который является возвращаемым значением, если поиск не увенчался успехом.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню