PDA

View Full Version : سوال: مشکل با gets در حلقه تکرار



Sundown
یک شنبه 13 دی 1388, 16:03 عصر
با سلام
دوستان کد زیر رو در ویژوال سی پلاس پلاس 2008 نوشتم در حلقه و در بار اول اجرای حلقه تابع gets اجرا میشه و در دفعات بعد سیستم از اون میگذره و رشته ای رو دریافت نمیکنه.
لطفا دلیل رو شرح دهید
با تشکر


\\Created (file://\\Created) With Microsoft Visual Studio 2008
#include "stdafx.h"
#include <conio.h>
#include <cstring>
#include <iostream>
using namespace std;
struct daneshjo{
char name[15];
char famil[15];
long double sd;
}Arr[5];

int main()
{
int i;
cout<<"Enter Data\n";
for(i=0;i<5;i++)
{
cout<<"enter name: ";

///Error Here
gets(Arr[i].name);
//////////////////
cout<<"enter family: ";
gets(Arr[i].famil);

cout<<"enter shoma d: ";
cin>>Arr[i].sd;
}
return 0;
}

clover
یک شنبه 13 دی 1388, 17:21 عصر
لطفا دلیل رو شرح دهید
متاسفانه دلیلش را دقیقا نمی دونم اما بعد از cin، یک کاراکتر 'n\' در جریان ورودی باقی میمونه که باعث پایان یافتن تابع gets بدون ورود رشته میشه.
برای رفع مشکل این خط را در انتهای حلقه (بعد از cin) اضافه کنید:

cin.ignore();

تاپیک مرتبط:

http://barnamenevis.org/forum/showthread.php?t=176137

Sundown
یک شنبه 13 دی 1388, 17:29 عصر
مرسی از پاسختان اما برای حل مشکل هزار و یک راه وجود داره اما من دنبال دلیلش هستم

به هر حال تشکر

clover
یک شنبه 13 دی 1388, 17:42 عصر
اما من دنبال دلیلش هستم
این هم دلیل:


std::cin.getline() can run into problems when used with std::cin >> var.
getline can be provided a third argument--a "stop" character. This character ends getline's input. The character is eaten and the string is terminated. Example:
std::cin.getline(str, 100, '|')
If std::cin.getline() is not provided a "stop" character as a third argument, it will stop when it reaches a newline.
Given:
float fl;
std::cin >> fl;
char str[101]
std::cin.getline(str, 101);
And you type: 3.14<return>
3.14 is read into fl . The newline following the 3.14 is still sitting on the input buffer.
std::cin.getline(str, 101) immediately processes the newline that is still on the input buffer. str becomes an empty string.
The illusion is that the application "skipped" the std::cin.getline() statement.

The solution is to add std::cin.ignore(); immediately after the first std::cin statement. This will grab a character off of the input buffer (in this case, newline) and discard it.

std::cin.ignore() can be called three different ways:
No arguments: A single character is taken from the input buffer and discarded:
std::cin.ignore(); //discard 1 character
One argument: The number of characters specified are taken from the input buffer and discarded:
std::cin.ignore(33); //discard 33 characters
Two arguments: discard the number of characters specified, or discard characters up to and including the specified delimiter (whichever comes first):
std::cin.ignore(26, '\n'); //ignore 26 characters or to a newline, whichever comes first
تقریبا همون چیزی بود که فکر می کردم.
منبع:

http://augustcouncil.com/~tgibson/tutorial/iotips.html