2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 cin.getline
Сообщение12.05.2008, 11:25 
Здравствуйте, я программирую на C++, компилятор Dev C++ 4.9.9.2.
При выполнении следующего кода я наблюдаю странное поведение функции cin.getline.

#include <iostream>

using namespace std;

main (int argc, char** argv)
{
char tStr [5];

for (int counter = 1; ; counter++)
{
cin.getline (tStr, 5);
cout << tStr;
}
return 0;
}

Если я ввожу строку, длина которой меньше, чем 5 символов, все в порядке. Но если я ввожу что-нибудь вроде "123456789", то уже начиная со второй итерации цикла либо (чаще всего) getline помещает '\0' в начало строки, либо программа зависает на cout << tStr. (проверено в отладчике). Что с этим делать?

 
 
 
 
Сообщение12.05.2008, 12:12 
Аватара пользователя
Во-первых, посмотрите описание функции в MSDN

Во-вторых, попробуйте увеличить объем статической памяти под массив. Думаю, что не хватает места под завершующий нуль-символ.

Кроме того, посмотрите в отладчике содержимое массива tStr после каждого шага.

 
 
 
 
Сообщение12.05.2008, 17:33 
PAV писал(а):
Во-первых, посмотрите описание функции в MSDN

Никому не посоветовал бы читать MSDN. Написано непонятно как.

MSDN писал(а):
After the function extracts an element that compares equal to _Delim, in which case the element is neither put back nor appended to the controlled sequence.

Так и не понятно, что происходит с прочитанным разделителем. Он всё ещё остался в потоке? Или нет? Будет ли он считан при следующем вызове? (Или как повезеёт?)

Советую почитать тут (и вообще, хороший сайт, всё ясно написано): http://www.cppreference.com/cppio/getline.html
cppreference.com писал(а):
reads characters into buffer until ... a newline is encountered

Всё ясно: разделитель не читается из потока. Он там и остаётся. Поэтому последующие вызовы к getline() читают строку длины 0: "", до тех пор, пока мы не уберём из потока разделитель -- символ новой строки '\n'. И программа не зависает, она выполняет бесконечный цикл: getline() считал строку длиной 0 символов, вы её вывели, снова "считали", и "вывели"... Убрать символ '\n' удобно при помощи вызова cin.ignore(): http://www.cppreference.com/cppio/ignore.html Но, осторожно, вызывайте ignore() только если следующий символ -- '\n', иначе будете терять данные из ввода.

Мой совет: если вам не принципиально, в переменную какого типа читать ввод, лучше читайте в string, раз уж пишете на C++ придётся с ним разобраться, и лучше сделать это сразу.

 
 
 [ Сообщений: 3 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group