Что я не понимаю в getline+strings?

Это мой первый опыт использования stackoverflow. Мне не удалось найти нужную мне информацию о getline. Я учусь в классе простого программирования для инженерных переводов, поэтому код, который мы пишем, довольно прост. Все, что я пытаюсь здесь сделать, это поместить заданное пользователем количество вопросов и ответов в два разных массива. Мой цикл while выглядит так (я использовал цикл for, но переключился на while, просто чтобы посмотреть, перестанет ли он ломаться):

int main ()
{
    srand((unsigned)time(0));
    string quest1[100], answ1[100];
    int size1, x = 0, num, count1, visit[100], shuffle[100];
    fstream flashcard1; 

    cout << "flashcard.cpp by NAME\n" << endl;
    cout << "This program allows user to manipulate questions and answers for studying.\n" << endl;
    cout << "\nHow many flash cards will be entered(MAX 100)? ";
    cin >> size1;
    cout << endl;

    while(x < size1)
    {
        cout << "Enter Question: ";
        getline(cin , quest1[x]);
        cout << endl;
        x = x++;

        /*
        cout << "Enter Answer: " << endl;
        getline(cin,answ1[x]);
        cout << endl;
        flashcard1.open("flashcard1.dat", ios::app);
        flashcard1 << quest1[x] << " " << answ1[x] << endl;
        flashcard1.close();
        cout << "Data Stored." << endl;
        */
    }
}

Я отметил часть ввода ответа, а также сохранение данных в файл только для отладки. Когда я запускаю программу, она пропускает getline для первого вопроса, отображает второй цикл «Введите вопрос», а getline работает для остальных. Итак, если у меня есть size1 из 5, программа заполняет только позиции массива 1-4. Пожалуйста помоги. Это простая программа для карточек, которая будет делать то же самое, как если бы вы создавали карточки для изучения и перемешивания их.


person Brent    schedule 23.11.2011    source источник
comment
x = x++; — это неопределенное поведение. Это должно быть просто x++ (или ++x, или x += 1, или x = x + 1, или x -= -1....)   -  person Seth Carnegie    schedule 23.11.2011
comment
Это связано с тем, что x++ и ++x изменяют сам x, увеличивая/уменьшая его значение на 1. Однако вы не можете гарантировать, что присваивание произойдет до или после этого, поэтому x может быть присвоено значение x++ до того, как произойдет приращение или после такое бывает (в стандарте это просто не указано).   -  person John Humphreys    schedule 23.11.2011
comment
+1 за хороший первый вопрос о SO.   -  person John Dibling    schedule 24.11.2011
comment
Добро пожаловать в Stack Overflow. +1! Это не по теме вашего вопроса, но 1) Пожалуйста, не используйте endl, когда вы имеете в виду '\n'. std::cout << std::endl в точности эквивалентно std::cout << '\n' << std::flush. 2) Никогда не говорите использование пространства имен std;, даже если (особенно если) ваша книга или профессор говорят вам об этом. Импорт всего пространства имен std в вашу программу создает трудно идентифицируемые ошибки.   -  person Robᵩ    schedule 24.11.2011
comment
@Rob Я думаю, что это большое преувеличение насчет using namespace std;. Пока вы знаете, в чем опасность, вы можете делать это в очень контролируемых средах (например, в коротких программах с одним файлом).   -  person Seth Carnegie    schedule 24.11.2011
comment
@все спасибо за советы. В следующем семестре я пойду на первый урок информатики. Этот простой курс C++ для инженеров был моим первым погружением в программирование, и мне это очень нравится. Я собираюсь изучать информатику в качестве основного предмета, если мне понравится класс CS в следующем семестре. Что касается моего кода относительно того, что сказал Роб. Я даже не знаю, что делает std::cout. Я не думаю, что этот учитель очень хорошо разбирается в C++, или он просто хочет сделать класс максимально простым. Для уроков он просто дает нам ppt-файлы, которые учат нас 2-5 новым кодам C++ за класс. В любом случае спасибо всем за помощь, ребята!   -  person Brent    schedule 24.11.2011


Ответы (1)


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

cin >> size1;

Вы вводите число и нажимаете клавишу Enter. cin считывает целое число и оставляет символ новой строки непрочитанным в буфере, поэтому при вызове getline создается впечатление, будто вы сразу нажимаете клавишу ввода, а getline ничего не читает (поскольку останавливается перед чтением новой строки символ), отбрасывает новую строку и помещает пустую строку в quest1[0]. И именно поэтому остальные getline работают "правильно".

Добавьте cin.ignore('\n') над своим циклом, чтобы избавиться от затянувшегося '\n', и это должно заставить его работать, исключая другие ошибки в вашем коде.

И не забудьте изменить x = x++ только на x++, чтобы избежать UB.

person Seth Carnegie    schedule 23.11.2011
comment
Спасибо! Такого полезного сообщества я не встречал уже много лет! - person Brent; 24.11.2011
comment
@Brent, если это ответило на ваш вопрос, не забудьте поставить галочку рядом с ним, чтобы отметить это как ответ на ваш вопрос. - person Seth Carnegie; 24.11.2011
comment
Я прошу прощения. Я был в классе раньше и не мог отредактировать свою программу, но предположил, что это правильный ответ. Когда я добавил cin.ignore('n) над своим циклом, программа просто никогда не вызывает первый оператор cout в цикле, если только вы не нажмете ввод примерно полдюжины раз - person Brent; 24.11.2011
comment
@ Брент, хорошо, тогда попробуй cin.ignore(1). Я попробовал это сам, и это сработало. - person Seth Carnegie; 24.11.2011