آبجی
23rd August 2010, 03:42 PM
فرض کنيد ميخواهيد در برنامه يک مقدار متني را از کاربر بخوانيد و آن را پردازش کنيد و نتيجه را به کاربر نشان دهيد. مثلا قرار است از کاربر يکسري کلمه بگيريم و اگر کلمه مورد نظر برابر Click بود يک پيغام را براي کاربر نمايش دهيم.
در زبانهاي قديمي مثل C متغيري براي تعريف يک عبارت متني وجود ندارد، خب چه بايد کرد؟
در زبان C دو نوع داده وجود دارد: دادههاي عددي که خود شامل چند نوع هستند و ديگري کاراکتري. يک متغير کاراکتري يک کاراکتر را در خود نگه ميدارد مثلا ‘a’. خب حالا بر ميگرديم به مقاله هفته پيش و تعريف آرايه. گفتيم آرايه به مجموعهاي از دادهها اطلاق ميشود که همگي از يک نوع باشند.
حال اگر ما يک آرايه از کاراکترها داشته باشيم، ميتوانيم عبارتي مثل Click را در آن ذخيره کنيم چون در واقع Click يک آرايه است که از چند کاراکتر تشکيل شدهاست. طول اين آرايه ? است.
خب پس ما ميتوانيم بنويسيم:
Char stringvariable[5];
يا آن را مقداردهي اوليه کنيم:
Char srtringvariable[] = {‘C’,’l’,’i’,’c’,’k’};
به اين نوع متغير که آرايهاي از کاراکترهاست و ميتواند يک عبارت متني را در خود ذخيره کند، در اصطلاح رشته (string)، ميگويند. برخي از زبانهاي جديد مثل C++ و جاوا خودشان يک نوع متغير بهنام رشته (string) دارند. رشتهها را برخلاف بالا ميتوان طور ديگري نيز مقداردهي اوليه کرد، بهصورت زير:
Char stringvariable[] = “Click”;
براي دسترسي به کاراکترهاي يک رشته دقيقا مثل يک آرايه عمل ميکنيم، مثلا خروجي کد زير برابر i است.
Printf(“%c”,stringvariable[2]);
حالا که با نحوه تعريف يک مقدار رشتهاي آشنا شديم بايد بتوانيم مقدار اين متغير را از کاربر بگيريم. براي خواندن رشتهها روشهاي مختلفي وجود دارد. روش اول استفاده از توابع تعريف شده در C براي خواندن عبارات رشتهاي است.
Gets تابعي است که يک مقدار رشتهاي را از کاربر ميگيرد. تعريف تابع بهصورت زير است:
Char* gets(char* buffer);
اين تابع يک آرايه از رشتهکاراکترها را ميگيرد و عبارتي که کاربر وارد کرده را از کيبورد ميخواند و آن را در متغير ورودي خود ذخيره ميکند و همان مقدار را بهعنوان خروجي برميگرداند. (توجه داشته باشيد که char* در واقع همان آرايه است).
نکتهاي که در استفاده از اين تابع بايد رعايت کنيد، طول آرايه تعريف شده و طول عبارت وارد شده توسط کاربر است که در صورت بيشتر بودن مقدار وارد شده توسط کاربر برنامه شما با خطايBuffer Overflow روبهرو ميشود (در مقالههاي قبلي بهطور کامل در مورد اين خطا بحث شده است).
براي جلوگيري از اين کار بايد به کاربر اطلاع دهيد که نميتواند تعداد کاراکترهايي بيشتر از مقدار مشخص شده توسط شما را وارد کند، اما وقتي کد خود را کامپايل ميکنيد کامپايلر به شما يک هشدار بهصورت زير ميدهد:
'gets': This function or variable may be unsafe. Consider using gets_s instead.
<span lang="FA">
اين هشدار به شما ميگويد که تابع gets تابعي امن براي خواندن رشتهها نيست و بهتر است بهجاي آن از gets_s استفاده کنيد.
اين تابع علاوه بر buffer يک عدد صحيح را از ورودي دريافت ميکند که طول مجاز براي رشته دريافتي از سمت کاربر است. ضعف اين دو تابع اين است که کاراکترهاي وارد شده را تا زمان رسيدن به يک Enter از کاربر ميگيرد. يعني کاربر نميتواند يک متن چند خطي را در ورودي وارد کند.
براي رفع اين مشکل از روش ديگري براي خواندن رشته از کاربر استفاده ميکنيم. در اين روش يک کاراکتر مشخص را نشانه انتهاي رشته مورد نظر قرار ميدهيم و از کاربر ورودي ميگيريم تا زماني که کاراکتر مورد نظر را وارد کند.
while ((temp[i]=getchar())!='*') i++;
temp[i] = '\0';
کاراکتر \0، اين کاراکتر نشان دهنده پايان يک رشته است. از اين کاراکتر ميتوان براي چاپ رشته و محاسبه طول آن استفاده کرد.
اين کد، ورودي را از کاربر ميگيرد تا زماني که کاربر کاراکتر * را وارد کند. مقدار i طول رشته خوانده شده است كه با يک and منطقي ساده ميتوان کد بالا را طوري بازنويسي کرد که کاربر از يك حدي بيشتر کاراکتر وارد نکند و مشکل Buffer overflow ديگر رخ ندهد.
اما نمايش رشتهها در خروجي: براي نشان دادن يک متغير رشتهاي ميتوان از تابع puts استفاده کرد. اين تابع يک متغير رشتهاي را از ورودي گرفته و آن را در خروجي چاپ ميکند.
براي نمايش رشتهها در خروجي ميتوان از تابع printf نيز بهصورت زير استفاده کرد:
Printf(“%S”,text);
براي نمايش رشته نيز ميتوان از حلقه زير نيز استفاده کرد:
while(temp[i] != '\0')
putchar(temp[i++]);
در زبانهاي قديمي مثل C متغيري براي تعريف يک عبارت متني وجود ندارد، خب چه بايد کرد؟
در زبان C دو نوع داده وجود دارد: دادههاي عددي که خود شامل چند نوع هستند و ديگري کاراکتري. يک متغير کاراکتري يک کاراکتر را در خود نگه ميدارد مثلا ‘a’. خب حالا بر ميگرديم به مقاله هفته پيش و تعريف آرايه. گفتيم آرايه به مجموعهاي از دادهها اطلاق ميشود که همگي از يک نوع باشند.
حال اگر ما يک آرايه از کاراکترها داشته باشيم، ميتوانيم عبارتي مثل Click را در آن ذخيره کنيم چون در واقع Click يک آرايه است که از چند کاراکتر تشکيل شدهاست. طول اين آرايه ? است.
خب پس ما ميتوانيم بنويسيم:
Char stringvariable[5];
يا آن را مقداردهي اوليه کنيم:
Char srtringvariable[] = {‘C’,’l’,’i’,’c’,’k’};
به اين نوع متغير که آرايهاي از کاراکترهاست و ميتواند يک عبارت متني را در خود ذخيره کند، در اصطلاح رشته (string)، ميگويند. برخي از زبانهاي جديد مثل C++ و جاوا خودشان يک نوع متغير بهنام رشته (string) دارند. رشتهها را برخلاف بالا ميتوان طور ديگري نيز مقداردهي اوليه کرد، بهصورت زير:
Char stringvariable[] = “Click”;
براي دسترسي به کاراکترهاي يک رشته دقيقا مثل يک آرايه عمل ميکنيم، مثلا خروجي کد زير برابر i است.
Printf(“%c”,stringvariable[2]);
حالا که با نحوه تعريف يک مقدار رشتهاي آشنا شديم بايد بتوانيم مقدار اين متغير را از کاربر بگيريم. براي خواندن رشتهها روشهاي مختلفي وجود دارد. روش اول استفاده از توابع تعريف شده در C براي خواندن عبارات رشتهاي است.
Gets تابعي است که يک مقدار رشتهاي را از کاربر ميگيرد. تعريف تابع بهصورت زير است:
Char* gets(char* buffer);
اين تابع يک آرايه از رشتهکاراکترها را ميگيرد و عبارتي که کاربر وارد کرده را از کيبورد ميخواند و آن را در متغير ورودي خود ذخيره ميکند و همان مقدار را بهعنوان خروجي برميگرداند. (توجه داشته باشيد که char* در واقع همان آرايه است).
نکتهاي که در استفاده از اين تابع بايد رعايت کنيد، طول آرايه تعريف شده و طول عبارت وارد شده توسط کاربر است که در صورت بيشتر بودن مقدار وارد شده توسط کاربر برنامه شما با خطايBuffer Overflow روبهرو ميشود (در مقالههاي قبلي بهطور کامل در مورد اين خطا بحث شده است).
براي جلوگيري از اين کار بايد به کاربر اطلاع دهيد که نميتواند تعداد کاراکترهايي بيشتر از مقدار مشخص شده توسط شما را وارد کند، اما وقتي کد خود را کامپايل ميکنيد کامپايلر به شما يک هشدار بهصورت زير ميدهد:
'gets': This function or variable may be unsafe. Consider using gets_s instead.
<span lang="FA">
اين هشدار به شما ميگويد که تابع gets تابعي امن براي خواندن رشتهها نيست و بهتر است بهجاي آن از gets_s استفاده کنيد.
اين تابع علاوه بر buffer يک عدد صحيح را از ورودي دريافت ميکند که طول مجاز براي رشته دريافتي از سمت کاربر است. ضعف اين دو تابع اين است که کاراکترهاي وارد شده را تا زمان رسيدن به يک Enter از کاربر ميگيرد. يعني کاربر نميتواند يک متن چند خطي را در ورودي وارد کند.
براي رفع اين مشکل از روش ديگري براي خواندن رشته از کاربر استفاده ميکنيم. در اين روش يک کاراکتر مشخص را نشانه انتهاي رشته مورد نظر قرار ميدهيم و از کاربر ورودي ميگيريم تا زماني که کاراکتر مورد نظر را وارد کند.
while ((temp[i]=getchar())!='*') i++;
temp[i] = '\0';
کاراکتر \0، اين کاراکتر نشان دهنده پايان يک رشته است. از اين کاراکتر ميتوان براي چاپ رشته و محاسبه طول آن استفاده کرد.
اين کد، ورودي را از کاربر ميگيرد تا زماني که کاربر کاراکتر * را وارد کند. مقدار i طول رشته خوانده شده است كه با يک and منطقي ساده ميتوان کد بالا را طوري بازنويسي کرد که کاربر از يك حدي بيشتر کاراکتر وارد نکند و مشکل Buffer overflow ديگر رخ ندهد.
اما نمايش رشتهها در خروجي: براي نشان دادن يک متغير رشتهاي ميتوان از تابع puts استفاده کرد. اين تابع يک متغير رشتهاي را از ورودي گرفته و آن را در خروجي چاپ ميکند.
براي نمايش رشتهها در خروجي ميتوان از تابع printf نيز بهصورت زير استفاده کرد:
Printf(“%S”,text);
براي نمايش رشته نيز ميتوان از حلقه زير نيز استفاده کرد:
while(temp[i] != '\0')
putchar(temp[i++]);