PDA

View Full Version : مفهوم flush و buffer



sajjadrad
یک شنبه 27 تیر 1389, 17:10 عصر
با سلام.
اول از هر چیز بگم تو تاپیک ها جستجو کردم اما به نظرم درباره مشکلی که دارم بحثی نشده بود.

خب بعضی از دوستان اشاره کرده بودن که بافر همون رشته هست...اول از هر چیز میخوام بدونم مگه بافر "حافظه میانی" نیست؟

برنامه زیر رو ببینید:


#include<iostream>
#include<conio.h>
#include<string>
usingnamespace std;
int main()
{
string a;
cin>>a;
cout<<"#1:"<<a<<endl;
cin>>a;
cout<<"#2:"<<a;
getch();
return 0;
}


خب تو این برنامه یک رشته با نام a تعریف شده.وقتی برنامه به خط cin رسید منتظر میمونه تا کاربر رشته ای رو وارد کنه بعد از وارد کردن رشته توسط کاربر و فشردن کلید enter کل رشته به حافظه میانی یا همون بافر ریخته میشه.دستور cin رشته رو تا کاراکتر خط فاصله و یا انتهای خط و یا نال میخونه و تو متغیر میریزه.فرض کنید کاربر Hi dear رو وارد کنه..چون بین hi و dear خط فاصله وجود داره پس cin تا hi میخونه و تو متغیر میریزه.و وقتی رشته a برای اولین بار چاپ میشه عبارت hi بر روی نمایشگر ظاهر میشه...بحث endl بماند...وقتی برای دومین بار a توسط cin خونده میشه؛cin به بافر مراجعه میکنه و دوباره تا خط فاصله یا پایان خط یا نال میخونه و ایندفه عبارت dear رو تو a میریزه...

حالا مشکل من اینجاست:

ما میگیم که endl اول یه کاراکتر \n وارد میکنه و بعد flush رو صدا میزنه که فلاش همون بافر رو خالی میکنه...
خب اگه بافر خالی بشه پس باید وقتی برنامه به cin دوم میرسه به بافر مراجعه میکنه و وقتی که با بافر خالی مواجه میشه باید یک رشته جدید بگیره ولی برعکس مشاهده میکنیم که dear رو از بافر میخونه و تو متغیر میریزه...

خب اگه حرفای من اشتباست میتونید برنامه رو تست کنید..من این برنامه رو تو Visual C++‎ 2008 تست کردم و خروجیش همونطوری که توضیح دادم اینه:

http://s1.picofile.com/uploadsajjad/Pictures/cplusa.JPG

حالا اینجا.چند سوال پیش میاد:

یک تعریف درست از buffer به همراه مثال میخوام

اگه بعد از وارد کردن رشته و enter زدن رشته وارد بافر نمیشه...پس کجا میره که cin از روی اون میخونه؟

اگه flush بافر رو خالی میکنه پس چرا بعد از بکاربردن endl و خالی شدن بافر دوباره cin عبارت رو از بافر میخونه...

بعضی از دوستان گفتن endl سیستم رو مجبور به ریختن بافر تو خروجی میکنه! خب سوال اینجاست چه موقع رشته های ما وارد بافر میشن؟آیا در همون لحظه ای که کاراکتر به کاراکتر وارد میشه؟ خب پس چرا تو دستور زیر پس از سمیکلن رشته تو خروجی چاپ میشه؟


cout<<"Hi Dear";

اینجا که از endl یا \n استفاده نکردیم که بگیم Endl مجبور به ریختن بافر تو خروجی میکنه و \n به سیستم این اجازه رو میده که اگه سرش خلوت بود به خروجی بفرسته بافر رو!

حالا به برنامه زیر توجه کنید:



#include<iostream>
#include<conio.h>
#include<string>
usingnamespace std;
int main()
{
string a;
string b;
cin>>a;
cout<<"a:"<<a<<endl;
cin>>b;
cout<<"b:"<<b;
getch();
return 0;
}

تو این برنامه دو تا متغیر رشته ای با نام های a,b تعریف کردیم و ابتدا a رو خوندیم..در ورودی hi dear رو وارد کردیم و بعد b رو خوندیم اما جالب اینجاست که برنامه بجای خوندن b اون از اbuffer خوند.
یعنی خروجی ما اینطوری شد:

a:hi
b:dear

اگه کسی میتونه واقعا کمک کنه چون تمامی مفاهیم buffer و flush رو قاطی کردم...

خواهشا توضیحاتتون با مثال باشه...
مرسی

PC2st
یک شنبه 27 تیر 1389, 22:49 عصر
خب اگه بافر خالی بشه پس باید وقتی برنامه به cin دوم میرسه به بافر مراجعه میکنه و وقتی که با بافر خالی مواجه میشه باید یک رشته جدید بگیره ولی برعکس مشاهده میکنیم که dear رو از بافر میخونه و تو متغیر میریزه...
اگه flush بافر رو خالی میکنه پس چرا بعد از بکاربردن endl و خالی شدن بافر دوباره cin عبارت رو از بافر میخونه...در دستوراتی که شما نوشتید، endl بافر خروجی یعنی std::cout را flush می‌کند و هیچ تاثیری بر روی ورودی یعنی std::cin ندارد.


یک تعریف درست از buffer به همراه مثال میخوامبافر std::cout درون خودش و در شیئ از نوع std::streambuf قرار دارد.
بافر اطلاعات را (بطور سریع) در خود ذخیره می‌کند و سپس هر چند وقت یکبار این اطلاعات از بافر بر روی کنسول (که سرعت کمتری دارد) چاپ می‌شود.


اگه بعد از وارد کردن رشته و enter زدن رشته وارد بافر نمیشه...پس کجا میره که cin از روی اون میخونه؟بافر std::cin هم درون خودش قرار دارد و شما توسط عملگر << اطلاعات را از این بافر می‌گیرید.


بعضی از دوستان گفتن endl سیستم رو مجبور به ریختن بافر تو خروجی میکنه! خب سوال اینجاست چه موقع رشته های ما وارد بافر میشن؟آیا در همون لحظه ای که کاراکتر به کاراکتر وارد میشه؟ خب پس چرا تو دستور زیر پس از سمیکلن رشته تو خروجی چاپ میشه؟این کار یعنی flush کردن معمولا بطور خودکار صورت می‌گیرد اما برای اطمینان می‌توان بطور مستقیم خود ما این کار را انجام دهیم یا توسط endl یا flush.


تو این برنامه دو تا متغیر رشته ای با نام های a,b تعریف کردیم و ابتدا a رو خوندیم..در ورودی hi dear رو وارد کردیم و بعد b رو خوندیم اما جالب اینجاست که برنامه بجای خوندن b اون از اbuffer خوند.منظور شما را اگر خوب متوجه شده باشم؛ علت آن این است که بافر ورودی و بافر خروجی از هم جدا هستند.