PDA

View Full Version : سوال: دلیل کار نکردن کد زیر



Arashdn
پنج شنبه 02 آذر 1391, 18:50 عصر
سلام دوستان
در کد زیر
char choose;
string partNumb , desc;

while(1)
{
cin >> choose;
if(choose == 'y' || choose == 'Y')
{
system("CLS");
cout << "You Need to Enter values for your fist invoice\n\n";


cout << "Enter part number: ";
getline( cin, partNumb );
myInvoice.setPartNumber(partNumb);


cout << "Enter description: ";
getline( cin, desc );
myInvoice.setDescription(desc);

break;
}
}
نمیدونم چرا دستور
getline( cin, partNumb );
کلا اجرا نمیشه (یعنی برنامه می نویسه Enter part number و بعد تو همون خط ادامش می نویسه Enter description
ولی getline دوم بدون ایراد کار میکنه ؟؟!!!

myinvoice مربوط به یک شی ای هست که قبلا ساختم و ربطی به موضوع نداره ..

پیشاپیش از کمک دوستان سپاس گزارم ...

مسعود اقدسی فام
پنج شنبه 02 آذر 1391, 19:19 عصر
شاید بعد از cin بیرون if، کاراکتر enter بافر ورودی باقی می‌مونه و باعث می‌شه دستور خوندن بعدی هم بدون دریافت چیزی رد بشه. شاید.

choose رو به جای cin با get و getch و اینا دریافت کن. احتمالا درست می‌شه.

Arashdn
پنج شنبه 02 آذر 1391, 19:28 عصر
شاید بعد از cin بیرون if، کاراکتر enter بافر ورودی باقی می‌مونه و باعث می‌شه دستور خوندن بعدی هم بدون دریافت چیزی رد بشه. شاید.

choose رو به جای cin با get و getch و اینا دریافت کن. احتمالا درست می‌شه.
فرقی نکرد .....
دقیقا باید چطور از این دستور استفاده کنم؟
choose=getch();
زدم بازم مثل cin شد ...

مسعود اقدسی فام
پنج شنبه 02 آذر 1391, 19:59 عصر
cin.get() چطور؟

بعد خوندن choose با هر روشی که دوست داشتی یه get فرمالیته بذار تا ببینیم حل می‌شه. اگه حل بشه یعنی بافر پر بوده که این دومی خالی کرده.

Arashdn
پنج شنبه 02 آذر 1391, 20:17 عصر
cin.get() چطور؟

بعد خوندن choose با هر روشی که دوست داشتی یه get فرمالیته بذار تا ببینیم حل می‌شه. اگه حل بشه یعنی بافر پر بوده که این دومی خالی کرده.
نشد
حتی به این شکل هم درش اوردم بازم همون آش و همون کاسه است ...
char choose;
//cin >> choose;
choose = 'y';

مسعود اقدسی فام
پنج شنبه 02 آذر 1391, 20:26 عصر
این حالت رو امتحان کردی؟




cin >> choose;

cin.get();




مقدار choose مهم نیست. بافر صفحه کلید مهمه.

Arashdn
پنج شنبه 02 آذر 1391, 20:34 عصر
دلیل رو پیدا کردم اما راه حل نه
قبل تعریف choose چند خط بالاتر از تابع زیر استفاده کردم که با حذف این تابع مشکل حل میشه ولی تو تابع هر چی گشتم چیزی پیدا نکردم
int getIntNum(string message)
{

while(1)
{


cout << message;
string a;
cin >> a;
if(checkDigit(a))
{
//for using atoi function we must turn a string into a c_string using function c_str
int b = atoi(a.c_str());
if (b==2147483647)
{
cout << "Warning : Your entered number was too large it will be limited to 2147483647 \n\n";
}

if (b==-2147483648)
{
cout << "Warning : Your entered number was too small it will be limited to -2147483648 \n\n";
}

return b;
break;
}


else
{
cout << "Error : Please Enter an integer number \n\n";
continue;
}//else

}//while

}//getintnum

ویرایش :
یافتم
دیلیلش اینه که تو این تابع از cin >> a; برای گرفتن یه رشته استفاده کردم ....
حل شد ....

Arashdn
پنج شنبه 02 آذر 1391, 20:44 عصر
حدسم اشتباه بود
بازم نشد ...
عجب گیری کردیما ...

مسعود اقدسی فام
پنج شنبه 02 آذر 1391, 20:56 عصر
حدسم اشتباه بود
بازم نشد ...
عجب گیری کردیما ...

بعد گرفتن choose این رو بزن ببینیم درس می‌شه:



setbuf(stdin, NULL)

رامین مرادی
پنج شنبه 02 آذر 1391, 22:04 عصر
سلام اگه سوالت رو درست فهميده باشم برو تو تايپيك زير
http://barnamenevis.org/showthread.php?338039-آموزش-نحوه-گرفتن-رشته-هایی-که-با-spase-جدا-شده-اند
احوال آقاي اقدسي فام ....

pr0tector
جمعه 03 آذر 1391, 00:35 صبح
سلام دوست عزیز
همونطور که جناب اقدسی فام فرمودند... اگه قبل از دستور getline از دستور ورودی دیگری مثل cin یا scanf و..استفاده کنید...بافر خالی نمیشه بنابراین getline اولی رد میشه و دومی اجرا میشه...برای خالی کردنش هم از دستورات زیر در زبان C++‎ میتونید استفاده کنید

memset(buf, 0, 3); // This Line Fill The buffer with zero
std::cin.clear(); // This Line reset The Stream State


البته اگه بافر رو هم خالی نکردید میتونید از دوتا getline پشت سرهم استفاده کنید...
یه تابع به اسم flush هم هست که فک کنم عضو namespace ، std باشه ،از اون هم برای خالی کردن بافر میتونید استفاده کنید..

mr AHR
جمعه 03 آذر 1391, 01:05 صبح
برای خالی کردن بافر از flush یا endl ( دومی یک "\n" هم خودش اضافه میکنه ) استفاده کنید به صورت زیر :

ostream << "Samle text" << flush

تو خط 13 و 18 اضافه کنین احتمالا کار میکنه
اینجا (http://www.cplusplus.com/reference/iostream/manipulators/flush/)رو بخونین منطق کار رو 100% میفهمین

Arashdn
جمعه 01 دی 1391, 11:01 صبح
به جز دستور flush (که طرز استفاده شو پیدا نکردم)همه رو تست کردم و هیچ کدوم بافری رو که بیشتر از یه کاراکتر باشه خالی نمیکنه
راهی هست که بافر رو (حالا ممکنه توش هیچی نباشه و ممکنه 50 تا کاراکتر باشه) کاملا خالی کنیم

omidshaman
جمعه 01 دی 1391, 11:06 صبح
cin.clear() + cin.ignore


cin.clear()

cin.ignore(50,'\n');

Arashdn
جمعه 01 دی 1391, 11:11 صبح
cin.clear() رو امتحان کن
البته فکر کنم بعدش باید از cin.ignore هم استفاده بشه

cin.ignore(50,'\n');
این
cin.ignore(50,'\n');
فک کنم فقط \n رو از بافر حذف میکنه
من میخوام همه چی پاک بشه

خود cin.clear تنها هم که تاثیری نداشت ....

omidshaman
جمعه 01 دی 1391, 11:41 صبح
فک کنم فقط \n رو از بافر حذف میکنه
نه اون یک خط رو پاک می کنه
یک همچین چیزی کل بافر رو پاک کنه البته به شرطی که a فایل stream باشه

while(!a.eof())
a.ignore(10,'\0');

شما دقیقا می خوای چکار کنی؟

Arashdn
جمعه 01 دی 1391, 13:26 عصر
نه اون یک خط رو پاک می کنه
یک همچین چیزی کل بافر رو پاک کنه البته به شرطی که a فایل stream باشه

while(!a.eof())
a.ignore(10,'\0');

شما دقیقا می خوای چکار کنی؟
برنامه من یه
Sleep(5000)
داره ، میخوام اگه کاربر تو 5 ثانیه کلیدی وارد کرد در عملیات بعدیش تاثیر نداشته باشه ....

omidshaman
جمعه 01 دی 1391, 17:01 عصر
راهی که C++‎‎ خالص باشه فکر نمی کنم وجود داشته باشه! چون معلوم نیست تو اون 5 ثانیه کاربر چی وارد کنه!! ممکنه اصلا اینتر نزنه ممکنه 10 بار بزنه
این cin.ignore(50,'\n'); فقط برای وقتایی کار می کنه که یک بار اینتر زده بشه که خوب معلوم نیست چند بار طرف اینتر رو بزنه!!
این کد win32 رو نگاه کن دقیقا کاری که میخوای رو انجام میده
البته بهتر بود این سوالتو توی یک تاپیک جدا میپرسیدی!

#include <iostream>
#include <windows.h> //for Windows-specific console stuff
#include <limits> //for numeric_limits

#undef max //disable the globally visible "max" macro

int main()
{
HANDLE hConsole = GetStdHandle( STD_INPUT_HANDLE );

//Start off with some basic console I/O
double move = 0;

std::cout << "Please enter the move: ";
std::cin >> move;
std::cin.sync();

std::cout << "Move entered: " << move << std::endl;

//Now, start the sleep cycle to allow the program to do whatever
//it has to do (and discard user input in the process)

std::cout << "Starting to sleep" << std::endl;

//Save the current console mode
DWORD originalConsoleMode;
GetConsoleMode( hConsole, &originalConsoleMode );

//Now turn the ENABLE_ECHO_INPUT flag off
//This makes it so any user input is not reflected on the screen
DWORD mode = 0;
SetConsoleMode( hConsole, mode & ~ENABLE_ECHO_INPUT );

Sleep(5000);

//Remove any input during the sleep cycle
FlushConsoleInputBuffer( hConsole );

//Restore original console mode
SetConsoleMode( hConsole, originalConsoleMode );

//Sleep cycle complete
std::cout << "Sleeping has ended" << std::endl;

//Read a move again (any input during the sleep cycle should not affect this)
std::cout << "Please enter another move: ";
std::cin >> move;
std::cin.sync();

std::cout << "Move entered: " << move << std::endl;

std::cout << std::endl << "Press ENTER to continue" << std::endl;
std::cin.ignore( std::numeric_limits< std::streamsize >::max(), '\n' );

return 0;
}

Arashdn
جمعه 01 دی 1391, 19:09 عصر
راهی که C++‎‎ خالص باشه فکر نمی کنم وجود داشته باشه! چون معلوم نیست تو اون 5 ثانیه کاربر چی وارد کنه!! ممکنه اصلا اینتر نزنه ممکنه 10 بار بزنه
این cin.ignore(50,'\n'); فقط برای وقتایی کار می کنه که یک بار اینتر زده بشه که خوب معلوم نیست چند بار طرف اینتر رو بزنه!!
این کد win32 رو نگاه کن دقیقا کاری که میخوای رو انجام میده
البته بهتر بود این سوالتو توی یک تاپیک جدا میپرسیدی!

#include <iostream>
#include <windows.h> //for Windows-specific console stuff
#include <limits> //for numeric_limits

#undef max //disable the globally visible "max" macro

int main()
{
HANDLE hConsole = GetStdHandle( STD_INPUT_HANDLE );

//Start off with some basic console I/O
double move = 0;

std::cout << "Please enter the move: ";
std::cin >> move;
std::cin.sync();

std::cout << "Move entered: " << move << std::endl;

//Now, start the sleep cycle to allow the program to do whatever
//it has to do (and discard user input in the process)

std::cout << "Starting to sleep" << std::endl;

//Save the current console mode
DWORD originalConsoleMode;
GetConsoleMode( hConsole, &originalConsoleMode );

//Now turn the ENABLE_ECHO_INPUT flag off
//This makes it so any user input is not reflected on the screen
DWORD mode = 0;
SetConsoleMode( hConsole, mode & ~ENABLE_ECHO_INPUT );

Sleep(5000);

//Remove any input during the sleep cycle
FlushConsoleInputBuffer( hConsole );

//Restore original console mode
SetConsoleMode( hConsole, originalConsoleMode );

//Sleep cycle complete
std::cout << "Sleeping has ended" << std::endl;

//Read a move again (any input during the sleep cycle should not affect this)
std::cout << "Please enter another move: ";
std::cin >> move;
std::cin.sync();

std::cout << "Move entered: " << move << std::endl;

std::cout << std::endl << "Press ENTER to continue" << std::endl;
std::cin.ignore( std::numeric_limits< std::streamsize >::max(), '\n' );

return 0;
}
ممنون از شما
اما سواد ما به اینجور کد های سخت قد نمیده .....

Arashdn
شنبه 02 دی 1391, 16:44 عصر
یعنی راه ساده تری نداره؟