2016-02-15 3 views
1

Эта программа дает мне странную ошибку, которую я просто не могу понять, она говорит о вещах вне объекта диапазона. Когда я запускаю эту программу без std::cin >> firstLast;, вместо этого я просто жестко программирую строку firstLast во что-то другое, она работает. Я этого нигде не видел и много дней искал, почему это не работает.Программа не печатает требуемую строку

#include "stdafx.h" 
#include <string> 
#include <iostream> 

int main() 
{ 
    //Declaring firstLast string 
    std::string firstLast; 

    //Asking for input for last and first name (same string) 
    std::cout << "Enter your first and last name below." << "\n>>"; 

    //Getting firstLast value from user 
    std::cin >> firstLast; 

    //This finds the space in the string so I can seperate the first and last name into different strings 
    int index = firstLast.find(' '); 

    /* 
    This makes a substring. The substring starts at index (the beginning of the surname) and goes on for the size of the surname (which is equal to the length of firstLast - first name length). 

    Ex: Name - "John Hopkins" 

    Length of "John" = 4 
    Length of " Hopkins" = firstLast.length() - 4 
    */ 
    std::string lastName = firstLast.substr(index, firstLast.length() - index); 

    //Printing the found surname 
    std::cout << "Your surname is " << lastName << "." << std::endl; 

    int rnd; std::cin >> rnd; return 0; 
} 

Я действительно не знаю, почему это не работает, если я жестко закодировать строку firstLast, он работает, но когда я использую КИН, чтобы получить строку, он выходит из строя и дает мне ОШИБКА:

Unhandled exception at 0x7626D928 in Test.exe: Microsoft C++ exception: std::out_of_range at memory location 0x0018F374. 
+3

Сразу после 'std :: cin >> ...', поместите в' std :: cout << firstLast << std:; endl; 'и посмотрите, что он вам скажет. – Beta

+0

Избавьтесь от '#include ', потому что это не обязательно в небольших программах. Преимущества прекомпиляции заголовков в небольших программах не являются существенными. –

+0

'firstLast.substr (index, firstLast.length() - index)' => на самом деле, вы можете уйти с 'firstLast.substr (index)', потому что по умолчанию 'substr' берет все, начиная с' index', до тех пор, пока конец. Второй аргумент действительно необходим, только если вам нужно сократить до конца. –

ответ

1

std::cin по умолчанию будет читать до тех пор, пока не увидит пробелы.

Так что в вашем случае, если вы вводите Joe Smith, firstLast будет содержать слово Joe и Smith будет сидеть в потоке ждать, чтобы быть извлечены.

Это значит, что std::string::find собирается вернуть std::string::npos, что означает, что ваш звонок в std::string::substr будет неправильным.

Чтобы избежать этого, вы можете выполнить два вызова std::cin, чтобы получить имя и фамилию отдельно или использовать getline для извлечения всей строки.

+0

@BoPersson Исправлено. – lcs

3
int index = firstLast.find(' '); 

никогда не найти бы пробел в строке, так как

std::cin >> firstLast; 

уже читает только до следующего пробела.

Чтобы прочитать строку, содержащую пробелы использовать

std::getline(cin,firstLast); 

вместо этого.


Если вы используете функцию std::string::find() всегда проверять результат против string::npos перед использованием его в качестве значения индексации.

+0

Я хотел бы отметить, что использование 'int' здесь не поможет, потому что' std :: string :: npos', в 64 бит, будет иметь значение 64 бит, поэтому 'int' будет расширен и' index 'никогда не будет равным' std :: string :: npos' ... –

0

Здесь проблема в том, что вы используете cin, чтобы взять имя и фамилию с пробелом. Но свойство cin состоит в том, что он различает аргументы, основанные на символе пробела в консоли.

std::cin >> firstLast; 

после этой строки, firstLast будет иметь только "First Name". Sp после этого, если вы попытаетесь извлечь Last name, это вызовет ошибку в вашей программе в строке ниже.

std::string lastName = firstLast.substr(index, firstLast.length() - index); 

Пример: , если вы входите в «» Привет мир», он будет принимать только„Привет“

Вместо этого, вы можете взять имя и фамилию отдельно

.. Надеюсь, это поможет.

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