PDA

توجه ! این یک نسخه آرشیو شده می باشد و در این حالت شما عکسی را مشاهده نمی کنید برای مشاهده کامل متن و عکسها بر روی لینک مقابل کلیک کنید : برنامه نویسی c جلسه سوم-توابع ورودي و خروجي



Y@SiN
04-30-2010, 12:53 PM
فصل 3
توابع ورودي و خروجي
هدف کلی
آشنایی با هشت تابع ورودی و خروجی زبان C
هدفهای رفتاری
انتظار می‌رود پس از مطالعة این فصل دانشجو:
1. با کاربرد و ویژگیهای تابع خروجی printf() آشنا شود.
2. فرامین فرمت را در تابع آرگومان‌دار ‌printf() بشناسد.
3. با کاربرد و ویژگیهای تابع ورودی scanf() آشنا شود.
4. تفاوت و تشابه توابع printf() و scanf() را بداند.
5. با کاربرد و ویژگیهای تابع ورودی getchar() آشنا شود.
6. با کاربرد و ویژگیهای تابع خروجی putchar() آشنا شود.
7. با کاربرد و ویژگیهای تابع ورودی getche() آشنا شود.
8. با کاربرد و ویژگیهای تابع ورودی getch() آشنا شود.
9. با کاربرد و ویژگیهای تابع ورودی ـ خروجی gets() و puts() آشنا شود.
مقدمه
زبان C با مجموعه‌اي از توابع كتابخانه‌اي همراه است كه تعدادي از آنها تابع ورودي و خروجي‌اند. برخي از اين توابع متداول را كه اغلب در كتابخانه يا فايل stdio.h قرار دارند در اين فصل بررسي می‌کنیم.
توابع فرمت‌‌دار scanf و printf امکان انتقال اطلاعات ميان كامپيوتر و دستگاههاي ورودي و خروجي استاندارد را فراهم می‌کنند. در واقع این توابع فرمت‌‌دار روي داده‌‌هايي که به شکل پيش‌‌فرض براي کامپایلر شناخته شده‌اند عمل مي‌کنند. دو تابع getchar وputchar موجب انتقال يك كاراكتر به حافظه و بالعكس مي‌گردند. دو تابع gets و puts نيز ورود و خروج رشته‌ها را ساده‌تر مي‌سازند. برخي از توابع ورودي و خروجي به آرگومان نیاز ندارند. بعضي از اين توابع مقداري را برنمي‌گردانند. برخي به صورت مستقل به كار می‌روند و برخي ممكن است در داخل عبارات و دستورها به كار روند.
تابع printf()
داده‌‌هاي خروجي استاندارد در کامپيوتر با استفاده از اين تابع نوشته می‌شود. اين تابع به تعداد دلخواه آرگومان می‌پذيرد كه آرگومان اول داراي مفهوم خاص است و رشتة فرمت يا رشتة كنترل[2 (http://www.blogfa.com/Desktop/#_ftn2)ناميده مي‌شود. رشتة كنترل در داخل زوج گيومه قرار مي‌گيرد و شامل اطلاعات قالب‌‌بندي است؛ يعني، مشخص مي‌كند كه بايد چند قلم آرگومان داده چاپ شود و فرمت آنها چگونه است. فرم كلي اين تابع به صورت زير است.

printf ("control string", arguments list) ;
يا

printf ("control string", arg1, arg2,…, argn) ;
رشتة كنترل دربردارندة دو نوع اقلام داده است. نوع اول شامل رشته يا كاراكترهايي است كه به همان صورت روي صفحه نمايش داده خواهد شد. نوع دوم شامل فرامين فرمت است كه با علامت "%" آغاز مي‌گردد و به دنبال آن كد فرمت يا مشخص‌كنندة فرمت مي‌آيد. فرمان فرمت، قالب يا فرمت و تعداد متغيرها يا آرگومانهايي را كه بايد چاپ شوند مشخص مي‌سازد و به آن type conversion نيز مي‌گويند و در آن براي مشخص ‌ساختن فرمت هر آرگومان يك گروه از كاراكترها كه با "%" آغاز مي‌گردند به كار مي‌رود.
برخي مؤلفان كد فرمت را فرامين فرمت نيز مي‌گويند. فهرست كد يا فرامين فرمت كه در فرمان printf به كار می‌روند در جدول 3ـ1 نشان داده شده است.

جدول 3ـ1 فرامين فرمت در تابع printf ()

مفهوم فرمان فرمت
كد تبديل
داده‌ به صورت تك‌كاراكتر نمايش داده مي‌شود.


%c
داده به صورت عدد صحيح دهدهي علامت‌دار نمايش داده مي‌شود.


%d
داده‌ به صورت عدد صحيح علامت‌دار نمايش داده مي‌شود.


%i
داده به صورت عدد اعشاري، مميز شناور بدون نما يا توان نمايش داده مي‌شود.


%f
داده به صورت floating-point ولي به فرم نمايي يا علمي نمايش داده مي‌شود.


%e
داده به صورت floating-point به فرم %f يا %e (هركدام كوتاه‌‌تر باشد) نمايش داده مي‌شود.


%g
داده‌ به صورت عدد صحيح دهدهي بدون علامت نمايش داده مي‌شود.


%u
داده‌ به صورت رشته نمايش داده مي‌شود.


%s
داده به صورت عدد صحيح در مبناي 8 نمايش داده مي‌شود.


%o
داده به صورت عدد صحيح در مبناي 16 و بدون علامت‌ نمايش داده مي‌شود.


%x
پيشوندي كه با %o , %x , %u , %d براي معرفي مقدار صحيح بلند يا طولاني به كار می‌رود (مثل ld).


L
در مورد داده‌‌هاي از نوع اشاره‌گر به كار می‌رود.


%p
علامت % چاپ مي‌كند.


%%


v مثال3ـ1 در برنامة زير مقادير متغيرهايي از نوعهاي مختلف در خروجي چاپ مي‌شود.



#include
main ()
{
int x =31 ;
float y =148.5 ;
char z[10] = {"PayamNoor"};
printf(" %d %f %s " , x , y , z) ;
}




اولي عدد صحيح دهدهي، دومي از نوع اعشاري و سومي رشته است كه به ترتيب با فرمان فرمت %s ,%f , %d مشخص شده‌اند. خروجي دستور مزبور به صورت زير خواهد بود.

31 148.5 PayamNoor
در برنامة مذكور به‌علت وجود يك محل خالي بين فرامين فرمت در رشتة كنترل، بين مقادير چاپ شده نيز فضاي خالي ايجاد شده است.

v مثال 3ـ2 به‌اين برنامه توجه کنيد.






#include
main ()
{
float x=2.0 , y=3 ;
printf("%f %f %f %f %d", x , y , x+y , x*y, x) ;
}

خروجي برنامه به صورت زير خواهد بود.
2.000000 3.000000 5.000000 6.000000 2
در اينجا آرگومانهاي اول و دوم تك‌متغيرند. ولي آرگومانهاي سوم و چهارم عبارات محاسباتي‌اند كه اول مقدار آنها محاسبه مي‌گردد و سپس نتيجه براساس كد فرمت مربوط چاپ مي‌شود. آرگومان آخر به شکل عدد صحيح چاپ مي‌شود.





مثال 3ـ3 به برنامة زير توجه کنيد.






#include
main ()
{
double x=50.0 , y=0.25 ;
printf(" %f %f %f %f\n ", x , y , x*y , x / y) ;
printf(" %e %e %e %e ", x , y , x*y , x / y) ;
}




هر دو دستور printf داراي آرگومانهاي يكسان‌اند ولي يکي با فرمان فرمت %f و در ديگري با فرمان فرمت %e چاپ شده‌اند. همچنين علامت "\n" موجب چاپ خروجي در سطر بعدي مي‌گردد.
خروجي اين برنامه به صورت زير خواهد بود.
50.000000 0.250000 12.500000 200.000000
5.000000e+01 2.500000e-01 1.250000e+01 2.000000e+02
در سطر اول مقادير x/y , x*y , y , x به فرم استاندارد floating point نشان داده شده، درحالي‌كه در سطر دوم همان مقادير به‌ دليل استفاده از فرمان فرمت "%e" به فرم نمايش علمي چاپ شده است.
ملاحظه می‌كنيد كه هر مقدار تا 6 رقم دقت، پس از نقطة اعشار نمايش داده شده است. به هرحال اين تعداد ارقام را مي‌توان با قرار دادن ميزان دقت در رشتة كنترلي تغيير داد.
در فرمان فرمت مي‌توان حداقل پهناي ميدان و تعداد ارقام اعشار، يعني ارقام بعد از مميز، را نيز مشخص كرد. همچنين مي‌توان تعيين كرد كه اطلاعات خروجي از سمت چپ ميدان چاپ (يعني فضاي تعيين‌‌شده براي چاپ) تراز گردند (در حالت عادي اطلاعات رشته‌اي از طرف چپ و اطلاعات عددي از سمت راست ميدان تراز مي‌شوند). حداقل طول ميدان را مي‌توان با قرار دادن يك عدد صحيح (به عنوان مشخص‌كنندة حداقل فضاي لازم) بين علامت % و كد فرمت مشخص كرد. اين كار موجب مي‌گردد كه اگر طول ميدان بيشتر از طول مورد نياز براي اطلاعات خروجي باشد، فضاي اضافي خالي باقي بماند. ولي اگر طول رشته يا عدد بزرگ‌تر از طول پيش‌بيني‌‌شده براي آن باشد، طول پيش‌بيني‌‌شده ناديده گرفته می‌شود و اطلاعات به طور كامل نمايش می‌یابد. اگر بخواهيد در مورد اطلاعات عددي فضاي اضافي با صفر پر شود، سمت چپ عدد m رقم "0" را قرار دهيد. براي مثال %04d موجب مي‌گردد كه اگر مقدار چاپ شده از چهار رقم كمتر باشد، سمت چپ آن به تعداد لازم صفر قرار گيرد به طوري كه مقدار چاپ شده چهار‌رقمي باشد.
در مورد مقادير floating point براي مشخص ساختن تعداد ارقام بعد از مميز، بايد پس از عدد مشخص‌كنندة طول ميدان، علامت مميز "." و پس از آن نيز يك عدد كه معرف تعداد ارقام اعشار خواهد بود قرار داد. براي مثال كد فرمت %10.4f عدد را با حداقل ده كاراكتر پهناي ميدان و با چهار محل براي ارقام اعشار نمايش خواهد داد.

مثال 3ـ4 به برنامة زير دقت کنيد.




#include
main ()
{
int x = 12345 ;
float y =345.125 ;
printf("3d %5d %8d\n\n", x , x , x) ;
printf("%3f %10f %13f\n", y , y , y) ;
printf("%3e %10e %13e\n", y , y , y) ;
printf("%g %10g %13g \n", x , x , x) ;
printf("%3g %10g %13g ", x , x , x) ;
}




خروجي اين برنامه به صورت زير خواهد بود.
12345 12345 12345
345.125000 345.125000 345.125000
3.45125e+02 3.45125e+02 3.45125e+02
345.125 345.125 345.125
345.125 345.125 345.125
در سطر اول، خروجي با استفاده از مينيمم پهناي فيلد (به طول سه كاراكتر، پنج كاراكتر و هشت كاراكتر) چاپ شده است. در هر فيلد تمامي عدد به طور كامل نمايش داده شده است، اگرچه طول ميدان پيش‌بيني شده كمتر از عدد مورد نظر است (مانند فيلد اول كه مينيمم طول پيش‌بيني شده سه كاراكتر است ولي عدد مورد نظر 5 رقمي است).
دومين خروجي در سطر اول با يك محل خالي شروع شده است. اين محل خالي به‌علت وجود يك محل خالي بين فرمان فرمت فيلد اول و دوم در رشتة كنترلي است.
سومين خروجي در سطر اول داراي چهار محل خالي يا blank در سمت چپ است كه يك محل آن به سبب وجود يك محل خالي بين فرمان فرمت فيلد دوم و سوم در رشتة كنترلي است. سه محل خالي ديگر نيز براي پركردن حداقل فضاي پيش‌بيني شده براي ميدان مورد نظر است (كه در اينجا هشت كاراكتر براي يك عدد پنج رقمي است).
شرايط مشابهي در سطر دوم و سوم خروجي وجود دارد. فقط بايد توجه كرد كه كد فرمت در سطر دوم از نوع f و در سطر سوم از نوع e است.
در سطر چهارم و پنجم همان مقادير با استفاده از کد فرمت %g چاپ شده است. اين فرم نتيجه را كوتاه‌تر نشان مي‌دهد. فواصل بين مقادير چاپ شده نيز براساس درنظر گرفتن حداقل پهناي پيش‌بيني شده در رشتة كنترلي براي آرگومانهاي مورد نظر است.
مي‌توان ماكزيمم تعداد ارقام اعشار در مورد مقادير floating point يا ماكزيمم تعداد كاراكتر براي يك رشته را نيز مشخص كرد. مشخصة مورد نظر براي اين عمل، precision يا دقت ناميده مي‌شود. دقت مورد نظر، يك عدد صحيح بدون علامت است كه قبل از آن نيز يك علامت مميز "." قرار مي‌گيرد. اگر علاوه بر precision حداقل طول ميدان نيز مشخص شده باشد (كه معمولاً نيز همين طور است)، طول ميدان قبل از precision قرار مي‌گيرد و علامت مميز "." بين آن دو درج مي‌شود و كد فرمت پس از اين مجموعه كاراكترها مي‌آيد.
در مورد مقادير floating point اگر دقت پيش‌بيني شده براي ارقام اعشار كوچك‌تر از تعداد ارقام اعشار باشد، جزء اعشار گرد مي‌شود، به طوري كه تعداد ارقام آن با دقت يا precision پيش‌بيني شده مطابقت نمايد.

مثال 3ـ5 به‌اين برنامه توجه کنيد.






#include
main ()
{
float x =123.456 ;
printf("%7f %7.3f %7.1f\n", x , x , x) ;
printf("%12e %12.5e %12.3e", x , x , x) ;
}




خروجي اين برنامه به صورت زير خواهد بود.
123.456000 123.456 123.5
1.234560e+02 1.23456e+02 1.235e+02
سطر اول با ‌كد فرمت f ايجاد شده است. در اينجا عدد سوم به دليل وجود مشخصة دقت كه يك رقم اعشار در نظر گرفته شده گرد شده است. همچنين با درنظر گرفتن حداقل طول ميدان (هفت كاراكتر) در سمت چپ عدد سوم، دو محل فضاي خالي به دليل حداقل طول ميدان و يك محل فضاي خالي نيز به دليل وجود يك محل خالي بين فرمان فرمت فيلدهاي دوم و سوم ايجاد شده است.
سطر دوم با كد فرمت نوع e ايجاد شده و داراي مشخصه‌هاي مشابه سطر اول است. در اينجا هم عدد سوم گرد شده است تا با دقت پيش‌بيني‌‌شده، يعني 3 رقم اعشار، تطابق یابد. همچنين چهار فضاي خالي نيز با در نظر گرفتن حداقل طول ميدان (دوازده كاراكتر) و وجود يك محل خالي بين فرمان فرمت فيلدهاي دوم و سوم در سمت چپ آن ايجاد شده است.
v
ضرورتي ندارد كه مشخصة دقت با حداقل طول ميدان توأم به كار رود، بلكه مي‌توان مشخصة دقت را بدون ذكر حداقل طول ميدان نيز به كار برد. ولي به هرحال نقطة معرف اعشار بايد در جلوي آن به كار رود، مانند دستور زير.
printf(" %.4f ", x) ;
علاوه بر كاراكترهاي تبديل و پهناي ميدان و شاخص دقت، رشته كنترل يك نشانه يا flag نيز دارد كه در شكل ظاهري خروجي اثر مي‌گذارد. flag بلافاصله بعد از علامت (%) قرار مي‌گيرد. بعضي كامپايلرها اجازه مي‌دهند كه دو flag پشت سر هم درون يک مشخصة تبديل به كار روند. flagهاي متداول در زبان C در جدول 3ـ2 نمايش داده شده‌اند.

جدول 3ـ2 Flag هاي متداول

مفهوم و کاربرد
Flag
داده‌ها در داخل ميدان از سمت چپ تراز مي‌شوند. فضاهاي خالي لازم براي پركردن حداقل پهناي ميدان نيز از طرف راست يعني بعد از داده افزوده مي‌شود.


_
در مورد داده‌‌هاي عددي، علامت آن (+ يا -) نيز در جلوي آن ظاهر مي‌گردد. بدون استفاده از اين flag فقط در مورد مقادير منفي علامت آنها در خروجي ظاهر مي‌شود.


+
در مورد داده‌‌هاي عددي موجب مي‌شود كه فضاي خالي سمت چپ به جاي blank با صفر پرشود. البته فقط در مورد داده‌‌هايي به کار می‌رود كه از سمت راست تراز مي‌شوند.


0
در مورد هر داده عددي علامت‌دار و مثبت يك blank در جلوي آن ظاهر مي‌شود. اين نشانه اگر با نشانة (+) به کار رود آن را لغو مي‌كند.


▪ ▪


blankspace
باعث مي‌شود كه در جلوي داده‌‌هاي اكتال 0 و داده‌‌هاي هگزادسيمال 0x ظاهر شود.


#


(با نوع تبديل 0- و x-)
باعث مي‌شود كه در تمام اعداد floating-point علامت مميز "." ظاهر شود، حتي اگر عدد مورد نظر جزء اعشار نداشته باشد. همچنين در مورد نوع تبديل g از ناديده گرفته شدن صفرهاي بدون معني سمت راست جلوگيري مي‌كند.


#


(با نوع تبديل e- g-, f-,)


مثال 3ـ6 كاربرد فلاگها در مورد مقادير صحيح و اعشاري در برنامة زير نمايش داده شده است.






#include
main ()
{
int x =123 ;
float y =45.0 , z = -6.7 ;
printf(": %5d %7.0f %10.1e: \n", x , y , y) ;
printf(": %-5d %-7.0f %-10.1e: \n", x , y , z) ;
printf(": %+5d %+7.0f %+10.1e: \n", x , y , z) ;
printf(": %7.0f %#7.0f %7g %#g: " , y , y , z , z) ;
}




با اجراي برنامه خروجي زير حاصل مي‌شود كه در آن علامت ":" آغاز ابتداي ميدان و پايان انتهاي ميدان را نمايش مي‌دهد.
: 123 45 -6.7+00:
: 123 45 -6.7e+00:
: +123 +45 -6.7e+00:
:+123 +45 -6.7e+00:
: 45 45. -6.7 -6.500000:
خط اول خروجي را بدون استفاده از فلاگ نمايش مي‌دهد كه در آن هر عدد درون ميدان مشخص‌‌شده براي آن، از طرف راست تراز شده است. خط دوم همان اعداد را با استفاده از همان كاراكترهاي تبديل با پيش‌بيني يك فلاگ در هر گروه از رشته فرمت نمايش مي‌دهد، و ملاحظه مي‌كنيد كه‌اين بار به علت وجود فلاگ "-" همة اعداد از سمت چپ تراز شده‌اند. در خط سوم از فلاگ "+" استفاده شده است. در اين حالت اعداد مانند خط اول از سمت راست تراز مي‌شوند. اما علامت مربوط نيز (در هر دو حالت مثبت و منفي‌) در جلوي آنها ظاهر شده ‌‌است. در خط چهارم تركيب دو فلاگ "-" و "+" به کار رفته است. در اينجا ضمن اينكه اعداد به دليل وجود فلاگ "-" از سمت چپ تراز شده‌اند، علامت مربوط نيز به‌علت وجود فلاگ "+" در جلوي آنها ظاهر شده است. در خط پنجم دو مقدار مميز شناور را يكبار بدون وجود فلاگ و بار ديگر با استفاده از فلاگ "#" نمايش مي‌دهد و همان طور که ملاحظه مي‌شود نقش اين فلاگ آن است كه در مورد عدد 45 علامت مميز را نيز منظور داشته است و در مورد عدد دوم صفرهاي بدون ارزش بعد از مميز را نيز در كد فرمت "g" نمايش مي‌دهد.

مثال 3ـ7 برنامة زير چاپ اعداد را در مبناي 8 و 10 و 16 نمايش مي‌دهد.






#include
main ()
{
int x = 1234 , y = 0155 , z = 0xa06b ;
printf(": %6u %6o %6x: \n", x , y , z) ;
printf(": %-6u %-6o %-6x: \n", x , y , z) ;
printf(": %#6u %#6o %#6X: \n" , x , y , z) ;
printf(": %06u %06o %06X: ", x , y , z) ;
}




خروجي برنامه به صورت زير خواهد بود که در اينجا نيز علامت ":" ابتداي ميدان و پايان ميدان را در هر خط نمايش مي‌دهد.
: 1234 155 a06b:
:1234 155 a06b:
: 1234 0155 0XA06B:
:001234 000155 00A06B:
خط اول بدون استفاده از فلاگ، اعداد را بدون علامت و به ترتيب در مبناهاي 10، 8 و 16 در خروجي نمايش مي‌دهد. خط دوم همان داده‌ها را با همان كاراكتر تبديل و با استفاده از فلاگ "-" نشان مي‌دهد كه درنتيجه اعداد در فضاي پيش‌بيني‌‌شده براي آنها از سمت چپ تراز شده‌اند. در خط سوم از فلاگ "#" استفاده شده است. اين فلاگ موجب مي‌گردد كه در جلوي اعداد در مبناي 8 و 16 به‌ترتيب "0" و "0x" ظاهر شود. همچنين به سبب استفاده از حرف بزرگ "X" در كاراكتر تبديل، حروف موجود در اعداد مبناي 16، در خروجي به صورت حروف بزرگ (يعني 0XA06B) ظاهر شده‌اند. خط آخر نقش استفاده از فلاگ "0" را نمايش مي‌دهد. اين فلاگ موجب مي‌گردد كه سمت چپ اعداد به تعداد لازم با صفر پر شود. در اينجا نيز به علت استفاده از حروف بزرگ "X" در كاراكتر تبديل، حروف موجود در اعداد مبناي 16، در خروجي به صورت حروف بزرگ ظاهر شده‌اند.