Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.09.2010, 17:10   #1
maryan.vetrov
Пользователь
 
Регистрация: 07.06.2010
Сообщений: 75
По умолчанию fgets в цикле работает некорректно

Доброго времени суток! Программа на С. Столкнулся с проблемой и не могу понять почему так.
Объявлена структура. И в цикле пользователь должен ввести данные в эту структуру. Вот код
Код:
struct toolsData tools;
	
	printf("Vvedite nomer zapisi: ");
	scanf("%d",&tools.accNum);
        while(tools.accNum!=0){
	printf("Vvedite nazvanie instrumenta ?: ");
			fgets(tools.name,sizeof(tools.name),stdin);
			printf("Vvedite kolichestvo ?: ");
			scanf("%d",&tools.quantity);
			printf("Vvedite cenu ?: ");
			scanf("%f",&tools.price);
	printf("Vvedite nomer zapisi: ");
	scanf("%d",&tools.accNum);
	}
в результате выполнения после ввода номера записи, все выводится в одну строку и выглядит так:
Vvedite nazvanie instrumenta ?: Vvedite kolichestvo ?:
если же удалить первый ввод номера строки до начала цикла, а оставить его только в конце цикла, то первое выполнение цикла будет корректным, например вот так:
Vvedite nazvanie instrumenta ?: Instrument A
Vvedite kolichestvo ?: 10
Vvedite cenu ?: 50.00
После чего появиться строка:
Vvedite nomer zapisi:3
Вводим 3 например, и далее происходит тоже что и при первом варианте кода, с вводом номера записи перед входом в цикл:
Vvedite nazvanie instrumenta ?: Vvedite kolichestvo ?:
Т.е. выполняются подряд два оператора printf и ожидается ввод для считывания следующим оператором scanf, а считывание по функции fgets пропускается??? Если fgets при вводе имени заменить на scanf, все работает нормально. Но мне нужна fgets, т.к. имя инструмента может содержать пробелы. Расскажите пожалуйста в чем проблема?
Заранее благодарен.

Последний раз редактировалось Stilet; 30.09.2010 в 08:02.
maryan.vetrov вне форума Ответить с цитированием
Старый 29.09.2010, 18:13   #2
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2maryan.vetrov
потому что перед использованием fgets ты вызвал scanf. scanf читает ввод только до переноса строки НЕ ВКЛЮЧИТЕЛЬНО (либо спец символа, ctrl + d, например). а перенос строки останется в буфере. именно его и прочитал fgets. fgets же читает буфер до переноса строки ВКЛЮЧИТЕЛЬНО (точнее перенос строки он заменяет на признак конца). вот и получается, что в буфере у тя находится \n, и fgets только его и считывает

сбрасывай буфер перед чтением строки, fflush(stdin) например
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance

Последний раз редактировалось pproger; 29.09.2010 в 18:18.
pproger вне форума Ответить с цитированием
Старый 29.09.2010, 20:35   #3
maryan.vetrov
Пользователь
 
Регистрация: 07.06.2010
Сообщений: 75
По умолчанию

Спасибо pproger! Все правильно вы говорите, я попробовал, применил fflush(stdin), навсякий случай проверил возвращаемое значение, возвращает 0, но при этом программа выполняется по прежнему некоректно! Почему???
maryan.vetrov вне форума Ответить с цитированием
Старый 29.09.2010, 21:32   #4
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2maryan.vetrov
куда ты fflush вставил? весь код скинь
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 29.09.2010, 23:27   #5
kaljan775
:D
Форумчанин
 
Аватар для kaljan775
 
Регистрация: 26.09.2010
Сообщений: 570
По умолчанию

в каком месте ? в том же самом?
Пишу ПО, создаю сайты, делаю курсовые работы, за деньги
C#, .NET, MS SQL, AngularJS, HTML, jQuery
kaljan775 вне форума Ответить с цитированием
Старый 30.09.2010, 00:17   #6
maryan.vetrov
Пользователь
 
Регистрация: 07.06.2010
Сообщений: 75
По умолчанию

Вставил в начало цикла, перед вызовом fgets(), вот код:
Код:
printf("Vvedite nomer zapisi: ");
scanf("%d",&tools.accNum);
while(tools.accNum!=0){
fflush(stdin);
printf("Vvedite nazvanie instrumenta ?: ");
fgets(tools.name,sizeof(tools.name) ,stdin);
printf("Vvedite kolichestvo ?: ");
scanf("%d",&tools.quantity);
printf("Vvedite cenu ?: ");
scanf("%f",&tools.price);
printf("Vvedite nomer zapisi: ");
scanf("%d",&tools.accNum);
}
А не коректно работает точно также и в том же месте, что и без fflush().

Последний раз редактировалось Stilet; 30.09.2010 в 08:03.
maryan.vetrov вне форума Ответить с цитированием
Старый 30.09.2010, 00:21   #7
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

да, я неправильно ответил. вернее почему так происходит верно) только fflush по стандарту не обязан очищать *in потоки. но винда это позволяет (на работе как раз она и стоит, там пробовал). чистить можно через scanf
Код:
scanf("%*c");
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 30.09.2010, 01:43   #8
maryan.vetrov
Пользователь
 
Регистрация: 07.06.2010
Сообщений: 75
По умолчанию

Благодарю, заработала. Не сообразил я сам, так с помощью scanf почистить!
А про fflush, я почитал, да не обязана, и с полным уважением возвращает 0, просто прочитав буфер, но не очистив его. Пишу я под линукс, вот с ней этот трюк и не прошел. Говорите что под windows работает, приму к сведению.
Благодарю за своевременную и четкую помощь.
maryan.vetrov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Некорректно работает программа Dimakat Помощь студентам 2 07.09.2010 14:54
некорректно работает WaitForMultipleObjects bazilior Общие вопросы C/C++ 2 17.04.2010 20:15
fgets - работает не верно, и вообще тупит heart C++ Builder 14 29.11.2009 15:55
Некорректно работает запрос Arkuz БД в Delphi 9 20.08.2009 07:04
IdHTTP1 некорректно работает nike-p Работа с сетью в Delphi 9 23.07.2008 23:13