PDA

View Full Version : اجرا نشدن صحیح یک دستور در سی



kiarashk
یک شنبه 28 آبان 1391, 08:10 صبح
سلام دوستان
یه مشکل عجیبی برخورد کردم که دقیقا نمی فهمم از کجاست.
اول این که کد مربوط به سی هست نه سی پلاس پلاس
دوم این که من با gcc اول نوشتم اما بعد توی ویژوال استدیو و برلند هم تست کردم هیچ کدوم error یا warning ی ندادن.

اما موضوع از این قرار هست که داخل یک حلقه while من یک switch case قرار دادم و بعد از پایان switch یک Printf و یک scanf که یک متغییر را بخوانه و برای شرط حلقه مورد استفاده قرار بگیرد اما اتفاقی که می افته اینه که دستور printf دوبار پشت سر هم انجام می شه با استفاده از brakepoint متوجه شدم که بعد از وارد کردن یه مقدار از نوع char برای اویل اجرای دستور scanf دکمه انتر رو که بعنوان پایان تایپ ورودی می زنیم رو به عنوان کاراکتر برای دفعه بعد می خونه که غیر منطقی به نظر می اد.

یکی از دوستان پیشنهاد داد که بین دستور printf و scanf از دستور cin>>ws استفاده کنم که جواب هم داد اما اولا دستور مال سی پلاس پلاس هست و دوما اصلا چرا این اتفاق می افته

omidshaman
یک شنبه 28 آبان 1391, 09:43 صبح
شما کدتو بزار بهتر میشه نظر داد
و این که زیاد هم چیز عجیبی نیست وقتی که شما از scanf استفاده می کنی زمانی که برنامه به کاراکتر \n یا همون اینتر میرسه اونو دیگه دریافت نمی کنه یک راهشم اینه که بعد از scanf از getchar استفاده کنی که مال C++‎ هم نیست یا از gets استفاده کنی به جای Scanf یا راه های دیگه...

kiarashk
یک شنبه 28 آبان 1391, 15:11 عصر
شما کدتو بزار بهتر میشه نظر داد
و این که زیاد هم چیز عجیبی نیست وقتی که شما از scanf استفاده می کنی زمانی که برنامه به کاراکتر \n یا همون اینتر میرسه اونو دیگه دریافت نمی کنه یک راهشم اینه که بعد از scanf از getchar استفاده کنی که مال C++‎ هم نیست یا از gets استفاده کنی به جای Scanf یا راه های دیگه...

اتفاقا مشکل همین جاست که وقتی به کارکتز \n می رسه اون رو دریافت می کنه. اینم کد:


#include <stdio.h>

int main(void)
{
char var;

printf("please choose menu(a,b,c): \n");
scanf("%c" , &var );

//var=getch();
while (var !='x' && var != 'X') {
switch (var) {
case 'a':
case 'A':
printf("A \n");
break;
case 'b':
case 'B':
printf("B\n");
break;
case 'c':
case 'C':
printf("Cn");
break;
}
printf("please choose menu: \n");
scanf("%c",&var) ;

}
return 0;
}

نتیجه اجرا هم اینه:


please choose menu(a,b,c):
a
A
please choose menu:
please choose menu:


یادم نیست ولی یا getchar بود که درست عمل می کرد یا getch به هر حال با یه if هم تونستم مشکل رو حل کنم اما می خوام بدونم اصلا چرا باید این اتفاق بیفته؟

shahmohammadi
یک شنبه 28 آبان 1391, 20:13 عصر
سلام.
توضيحاتي رو كه دوستمون tdkhakpur (http://barnamenevis.org/member.php?99732-tdkhakpur) در اينجا نوشتند رو بخونيد:
رفتار دور از انتظار اين برنامه#6 (http://barnamenevis.org/showthread.php?286456-%D8%B1%D9%81%D8%AA%D8%A7%D8%B1-%D8%AF%D9%88%D8%B1-%D8%A7%D8%B2-%D8%A7%D9%86%D8%AA%D8%B8%D8%A7%D8%B1-%D9%8A%D9%87-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87&p=1262069&viewfull=1#post1262069)

اين هم اصلاح برنامه تون:
#include <stdio.h>

int main(void)
{
char var;

printf("please choose menu(a,b,c): \n");
scanf("%c" ,&var );

//var=getch();
while (var !='x' && var != 'X') {
switch (var) {
case 'a':
case 'A':
printf("A\n");
break;
case 'b':
case 'B':
printf("B\n");
break;
case 'c':
case 'C':
printf("C\n");
break;
}
fflush(stdin);
// printf("%d %c\n",var,var);
printf("please choose menu: \n");
scanf("%c",&var) ;

}
return 0;
}

و اما مشكل:
وقتي كه يك كاراكتر رو نوشته و اينتر مي زنيد اينتر هم در بافر scanf قرار مي گيره و در دفعه ي بعد به جاي اينكه از ورودي بخونه اون اينتر رو مي خونه. براي جلوگيري از اينكار من بنا به توضيحي كه دوستمون دادند از تابع fflush استفاده كردم تا مشكلتون حل شه.

shahmohammadi
یک شنبه 28 آبان 1391, 20:19 عصر
راستي: getch به اين دليل برنامه رو درست مي كرد كه اينتر رو كه در بافر بود دوباره مي گرفت.

kiarashk
یک شنبه 28 آبان 1391, 22:27 عصر
راستي: getch به اين دليل برنامه رو درست مي كرد كه اينتر رو كه در بافر بود دوباره مي گرفت.

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

kiarashk
دوشنبه 29 آبان 1391, 19:53 عصر
راستي: getch به اين دليل برنامه رو درست مي كرد كه اينتر رو كه در بافر بود دوباره مي گرفت.

متاسفانه دستور اجرا نشد اما حرفتون کاملا درست بود و سرنخ خوبی بود که بتونم مشکل رو حل کنم گویا توی کامپایلر های مختلف این دستور یکم فرق می کنه برای همین من توی gcc نتیجه نگرفتم و اصلا دستور بافر رو خالی نمی کرد به جاش این دستور رو پیدا کردم که به خوبی عمل کرد. اینجا به اشتراک گذاشتم که شاید دوست دیگه ای هم لازم داشت:


setbuf(stdin, NULL)