Проблеми с getline в Домашно от "Упражнение цикли 2", задача 2 - Exam Preparation
Здравейте,
За пореден път имам проблеми при използване на getline(cin,string);, като вместо в конзолата да чете вход, Visual (а и judge) директно прескачат реда, все едно не съществува.
Ето код от конкретната задача.
На редове 18 и 19 ще видите едно и също, а именно getline(cin, name);, където name е името на съответния пореден урок.
Логично погледнато би трябвало два пъти да се очаква вход при повторение на двата реда. Да, ама не. Така програмата работи и дава 100 точки в judge.
Ако изтрия дублиращият ред всичко отива по дяволите и getline не чете нищо, четат се само числата (оценките по съответния предмет, който getline е трябвало да "хване").
Въпросите са два:
1. Защо се случва това?
2. Кога се случва това и как да се избегне? Личните ми впечатления показват, че се случва при въвеждане поредно чрез getline и cin >>, но нали използваме getline заради проблема на >> с "white spaces" (не може да прочете фраза с интервал в нея, а взима стойността само на низа до интервала)?
Благодаря предварително за помощта. Минаха часове, докато успея да хвана защо всичко се дъни...
Ще тръгне при правилен синтаксис.
По-интересно ми е защо върви повторението на getline като един ред, че и присвоява коректно стойност.;)
Ами незнам условието на задачата, но както гледам имаш 2 стринга за име и фамилия. А викаш getline(cin, name); само. Това name всъщност ти е коя променлива подаваш на getline. То ти взима променливата от cin. С две думи направи 19ти ред на getline(cin, lastname);
А ако имаш в предвит че не съм сложил ; направих го нарочно за да го напиша в изречение.
Ето какво представлява cin.ignore();
http://www.cplusplus.com/reference/istream/istream/ignore/
Благодаря ти за линка, ползвал съм ignore по необходимост и знам , че си прав и ще работи.
Виж пак кода. Редове 18 и 19 са еднакви и теоретично в конзолата трябва два пъти подред да зададеш стойност на name. А на практика се случва веднъж и judge грее със сто точки.;)
Тоест, при един getline конзолата "прескача" реда, а при два - въвежда КОРЕКТНО веднъж.
Lastname само помни последно въведеното name и няма работа с конзолата. И тъй като name се променя при всяко повторение на цикъла, задавам на lastname "last known" стойност на name, защото един ден ще трябва да я принтвам.
За това иде реч - некоректното работи коректно, а коректното не работи изобщо.
Така е. Но cin си остава на същия ред. И това е причината за това нещо. cin ти взима до space, но не отива на нов ред. Докато getline ти взима целия ред и чака следващ. И в твоя случай както два пъти му извикаш да ти вземе name то първия ти взима каквито там фрагменти са останали от cin и счита реда за взет и слиза на новия. А след това на втория път ти взима същия ред и затова работи. Общо взето пускаш първия getline на същия ред на който е бил cin. Ако можеш да си пуснеш режим Debug на IDE-то ти, ще можеш стъпка по стъпка да видиш какво става. А за Judge на него му се подават предварително сетнати input и output и ако тези който твоя код приема и подава са на 100% еднакви с тези на Judge то тогава ти дава точките от тестовете.
Надявам се да съм ти помогнал.
Всъщност днес си играх доста.
И бях добавил "cout << name; " за да видя какво точно хваща. Хваща... Едно голямо нищо (каквото и има всъщност, защото при първия cin въвеждаш число и натискаш Enter, та няма "първи интервал", няма нищо).
Както и да е, стори ми се изключително нелогично поведението на Visual & judge.
Благодаря ти за помощта и отделеното време!
P.S. cin.ignore(); на мястото на първият getline работи коректно, както ти спомена.