std :: getline не работает внутри цикла for - PullRequest
5 голосов
/ 11 января 2010

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

Так как обычный cin >> str не принимает пробелы, я бы выбрал std :: getline из

Вот мой код:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
    int n;
    cin >> n;
    for(int i = 0; i < n; i++)
    {
        string local;
        getline(cin, local); // This simply does not work. Just skipped without a reason.
        //............................
    }

    //............................
    return 0;
}

Есть идеи?

Ответы [ 8 ]

12 голосов
/ 11 января 2010

Вы можете понять, почему это не работает, если вы выводите то, что вы сохранили в local (кстати, это плохое имя переменной: P):

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
    int n;
    cin >> n;
    for(int i = 0; i < n; i++)
    {
        string local;
        getline(cin, local);
        std::cout << "> " << local << std::endl;
    }

    //............................
    return 0;
}

Вы увидите, что он печатает новую строку после > сразу после ввода вашего номера. Затем он переходит к вводу остальных.

Это потому, что getline дает вам пустую строку, оставшуюся от ввода вашего номера. (Он читает число, но, по-видимому, не удаляет \n, поэтому у вас остается пустая строка.) Сначала необходимо избавиться от оставшихся пробелов:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
    int n;
    cin >> n;
    cin >> ws; // stream out any whitespace
    for(int i = 0; i < n; i++)
    {
        string local;
        getline(cin, local);
        std::cout << "> " << local << std::endl;
    }

    //............................
    return 0;
}

Это работает, как ожидалось.

Не по теме, возможно, это было только для фрагмента, но код, как правило, может быть больше читабельным, если у вас нет using namespace std;. Это побеждает цель пространств имен. Я подозреваю, что это было только для публикации здесь.

2 голосов
/ 05 февраля 2017

Объявите символ сядьте в карету вернитесь после того, как вы ввели номер. char ws;int n;cin>>n;ws=cin.get(); Это решит проблему.

Использование cin>>ws вместо ws=cin.get() сделает первый символ вашей строки в переменной ws вместо простого сброса '\n'.

1 голос
/ 11 января 2010

Я предполагаю, что вы не правильно читаете n, поэтому он конвертируется как ноль. Поскольку 0 не меньше 0, цикл никогда не выполняется.

Я бы добавил немного инструментов:

int n;
cin >> n;
std::cerr << "n was read as: " << n << "\n"; // <- added instrumentation
for // ...
1 голос
/ 11 января 2010

Вы нажимаете ввод? В противном случае строка ничего не вернет, так как она ожидает конца строки ...

0 голосов
/ 04 января 2018

Вы можете напрямую использовать функцию getline в строке, используя разделитель следующим образом:

#include <iostream>
using namespace std;
int main()
{
    string str;
    getline(cin,str,'#');
    getline(cin,str,'#');
}

вы можете вводить str столько раз, сколько хотите, но здесь применимо одно условие: вам нужно передать '#' (третий аргумент) в качестве разделителя, т.е. строка будет принимать ввод до тех пор, пока не будет нажата '#' независимо от символа новой строки.

0 голосов
/ 11 января 2010

Важный вопрос: «Что вы делаете со строкой, которая дает вам представление о том, что ввод был пропущен?» Или, точнее, «почему вы думаете, что ввод был пропущен?»

Если вы проходите через отладчик, скомпилировались ли вы с оптимизацией (что позволяет переупорядочивать инструкции)? Я не думаю, что это ваша проблема, но это возможно.

Я думаю, что более вероятно, что строка заполнена, но обрабатывается неправильно. Например, если вы хотите передать входные данные старым функциям C (например, atoi()), вам необходимо извлечь строку стиля C (local.c_str()).

0 голосов
/ 11 января 2010

На каком компиляторе вы пробовали это? Я пробовал на VC2008 и работал нормально. Если я скомпилировал тот же код на G ++ (GCC) 3.4.2. Это не сработало должным образом. Ниже приведены версии, работающие в обоих компиляторах. У меня нет последней версии g ++ компилятора в моей среде.

int n;
cin >> n;
string local;
getline(cin, local); // don't need this on VC2008. But need it on g++ 3.4.2. 
for (int i = 0; i < n; i++)
{
    getline(cin, local);
    cout << local;
}
0 голосов
/ 11 января 2010
  • Правильно ли инициализирован n из ввода?
  • Похоже, вы ничего не делаете с getline. Это то, что вы хотите?
  • getline возвращает ссылку на istream. Имеет ли значение тот факт, что вы бросаете его на землю?
...