Вопрос

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

Поскольку обычный cin >> str не принимает пробелы, поэтому я бы использовал std::getline из <string>

Вот мой код:

#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;
}

Есть идеи?

Это было полезно?

Решение

Вы можете понять, почему это не удается, если выведете то, что сохранили в 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;.Это противоречит цели пространств имен.Я подозреваю, что это было только для публикации здесь.

Другие советы

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

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

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

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

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

int n;
cin >> n;
std::cerr << "n was read as: " << n << "\n"; // <- added instrumentation
for // ...
  • Правильно ли инициализируется входной параметр n?
  • Похоже, вы ничего не делаете с getline.Это то, чего ты хочешь?
  • getline возвращает ссылку на istream.Имеет ли значение тот факт, что вы роняете его на землю?

На каком компиляторе вы это пробовали?Я пробовал на 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;
}

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top