2016-03-01 2 views
0
#include <iostream> 
#include <string> 
using namespace std; 
int main(){ 
    int a1,a2,a3,a4; 

cin>>a1>>a2>>a3>>a4; 
string a; 
getline(cin,a); 
return 0;} 

У меня есть этот код. Я не могу ввести значение «a». Помогите мне пожалуйстаC++ getline cin error

+1

Что вы подразумеваете под "can not input"? Любые ошибки? – songyuanyao

+0

только это, когда дело доходит до ввода, программа закрывается –

+0

Как вы их вводили? Я попробовал демонстрацию [здесь] (http://rextester.com/TGTZ9945). – songyuanyao

ответ

2

Вы можете использовать std::ws, чтобы отбросить ведущие пробелы из входного потока.

#include <iostream> 
#include <string> 

int main() 
{ 
    int a1, a2, a3, a4; 
    std::cin >> a1 >> a2 >> a3 >> a4; 

    std::string a; 
    std::getline(std::cin >> std::ws, a); 

    return 0; 
} 

cin фактически хранит целое число и '\n' во входном буфере.

Поэтому, когда поток достигает заявления getline, он получает только '\n'.


В любом случае чтение в цифрах напрямую проблематично: когда cin представлен с входом он не может обработать, он переходит в состояние строя.

Вход, который он не может обработать, остается на входном потоке и игнорируется до тех пор, пока не будет сброшено состояние «fail» (std::cin.clear()).

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

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

    // Get the input again/handle the error 
} 
1

Good documentation like cppreference.com объясняет проблему очень четко:

При использовании сразу после пробела разделителями ввода, например, после int n; std::cin >> n;, getline потребляет символ конечной линии слева от входного потока на operator>> и сразу возвращается.

Я хотел бы предложить альтернативное решение, чем игнорировать оставшийся символ. Обычно вы должны учитывать стиль программирования, в котором все входные данные основаны на линиях, с std::getline. В случае необходимости отдельные линии могут быть tokenised, используя такие инструменты, как std::istringstream или std::stoi. Это позволяет вам выполнять обработку ошибок для неправильного ввода гораздо проще, чем через флагов состояния std::cin.

Например, в следующей примерной программе, когда вы пытаетесь ввести меньше или больше 4 целых чисел в первой строке или если одно из целых чисел не может быть проанализировано как целое число, тогда вы получите точную ошибку сообщение. Важным моментом является то, что вместо того, чтобы использовать std::cin, чтобы получить прямо к целочисленным значениям, сначала получается первая строка std::string, а затем ее разделяют и анализируют.

#include <iostream> 
#include <string> 
#include <vector> 
#include <sstream> 
#include <stdexcept> 
#include <exception> 

// using just one of the many possible ways in C++ to tokenise a string: 
std::vector<std::string> tokenise(std::string const& line) 
{ 
    std::vector<std::string> tokens; 
    std::istringstream is(line); 
    std::string token; 
    while (std::getline(is, token, ' ')) 
    { 
     tokens.push_back(token); 
    } 

    return tokens; 
} 

std::vector<int> parse_four_integers(std::string const& line) 
{ 
    auto const tokens = tokenise(line); 

    if (tokens.size() != 4) 
    { 
     throw std::runtime_error("illegal token count: " + std::to_string(tokens.size())); 
    } 

    std::vector<int> result; 
    for (auto&& token : tokens) 
    { 
     try 
     { 
      result.push_back(std::stoi(token)); 
     } 
     catch (std::exception const&) 
     { 
      throw std::runtime_error("token " + token + " is not a valid integer"); 
     } 
    } 
    return result; 
} 

int main() 
{ 
    try 
    { 
     std::string line; 

     std::getline(std::cin, line); 
     auto const four_integers = parse_four_integers(line); 

     std::getline(std::cin, line); 

     for (auto&& integer : four_integers) 
     { 
      std::cout << integer << "\n"; 
     } 
     std::cout << line << "\n"; 
    } 
    catch (std::exception const& exc) 
    { 
     std::cerr << exc.what() << "\n"; 
    } 
}