آموزش رشته ها در برنامه نویسی C

در این آموزش با رشته ها در برنامه نویسی C آشنا خواهید شد، تعریف رشته ها، مقداردهی اولیه و استفاده از آنها برای عملیات های مختلف ورودی/ خروجی را به کمک مثال های مختلف یاد خواهید گرفت.
در زبان C، برعکس زبانهای مدرنتر، هیچ نوع دادهی مستقل و آمادهای برای تعریف «متن» وجود ندارد. رشتهها در این زبان، در واقع چیزی جز یک صف (آرایه) از کاراکترهای به هم پیوسته نیستند که در یک بلوک خطی از حافظه ذخیره میشوند و با یک علامت ویژه و پنهان به پایان میرسند.
ویژگیهای بنیادین رشتهها
-
نشانه پایاندهنده (Null Terminator): حیاتیترین و متمایزترین ویژگی رشتهها در C این است که حتماً باید با یک کاراکتر نامرئی به نام «کاراکتر تهی» تمام شوند. از آنجا که ساختارهای داده در C طول و اندازه خودشان را نمیدانند، این علامتِ پایاندهنده، تنها راهی است که به سیستم میفهماند متن دقیقاً در کجا تمام شده است.
-
ماهیت اشارهگری و آدرسمحور: وقتی شما با یک متن در زبان C کار میکنید، در واقع در حال کار با «آدرسِ اولین حرفِ آن متن» در حافظه هستید. سیستم عامل از آن آدرس شروع به خواندنِ حرفبهحرف میکند و رو به جلو میرود تا به نشانه پایاندهنده برخورد کند.
-
اندازه ثابت و غیرمنعطف: از آنجا که رشتهها در لایه زیرین فقط یک آرایه ساده هستند، تغییر اندازه آنها پس از ایجاد، به صورت خودکار غیرممکن است. اگر بخواهید متنی را به انتهای رشتهای اضافه کنید که فضای کافی ندارد، باید به صورت دستی فضای جدید و بزرگتری در حافظه درخواست کنید و متن را جابهجا کنید.
-
مسئولیت سنگین امنیتی: وابستگی مطلق سیستم به «کاراکتر پایاندهنده» پاشنه آشیل رشتهها در C است. اگر برنامهنویس در محاسبات خود اشتباه کند و این کاراکتر روی حافظه نوشته نشود یا پاک شود، سیستم برای پیدا کردن انتهای متن به خواندنِ خانههای غیرمجاز حافظه ادامه میدهد که این امر منجر به فروپاشی برنامه یا ایجاد حفرههای امنیتی خطرناک (مانند سرریز بافر) میشود.
هدف و فلسفه استفاده
فلسفه طراحی رشتهها در زبان C، فدا کردن راحتی برنامهنویس در ازای کنترل مطلق و شفافیت سختافزاری است.
طراحان این زبان به جای ایجاد یک ساختار سنگین، پیچیده و آماده (مانند آنچه در پایتون یا سیشارپ میبینیم)، پردازش متن را به ابتداییترین شکل ممکن یعنی «مدیریت تکتک بایتها در حافظه» تقلیل دادهاند. این رویکرد باعث میشود کار با متنها در زبان C نیازمند دقت بالا و مستعد خطاهای انسانی باشد، اما در عوض، سریعترین، سبکترین و بدونواسطهترین روش ممکن برای پردازش اطلاعات متنی در هسته سیستمعاملها، درایورها و سیستمهای دارای محدودیت شدید حافظه (Embedded Systems) را فراهم میآورد.
در برنامه نویسی C، رشته دنباله ای از کاراکترها است که با کاراکتر ۰ به اتمام می رسد. مثال:
char c[] = “c string”;
هنگامی که کامپایلر به دنباله ای از کاراکترهای محصور در علامت های نقل قول برسد، به طور پیش فرض در انتهای آنها کاراکتر ۰ را اضافه می کند.

تعریف رشته
نحوه تعریف رشته به شکل زیر است:
char s[5];

در اینجا یک رشته ۵ کاراکتری تعریف شده است.
مقداردهی اولیه رشته ها
می توانید رشته ها را به روش های مختلف مقداردهی اولیه کنید.
char c[] = “abcd”;
char c[50] = “abcd”;
char c[] = {‘a’, ‘b’, ‘c’, ‘d’, ‘�’};
char c[5] = {‘a’, ‘b’, ‘c’, ‘d’, ‘�’};

تخصیص مقدار به رشته
آرایه ها و رشته ها پس از تعریف، از عملگر انتساب پشتیبانی نمی کنند. مثال،
char c[100];
c = “C programming”; // خطا! نوع آرایه قابل انتساب نیست
نکته: به جای آن برای کپی یک رشته می توانید از تابع ()strcpy استفاده کنید.
دریافت رشته از کاربر
برای خواندن و دریافت یک رشته از ورودی می توانید از تابع ()scanf استفاده کنید. این تابع کاراکترهای پشت سر هم را می خواند تا به فاصله یا فضای خالی (فاصله، خط جدید، تب و …) برسد.
مثال ۱: ()scanf برای خواندن رشته های ورودی
#include
int main()
{
char name[20];
printf(“Enter name: “);
scanf(“%s”, name);
printf(“Your name is %s.”, name);
return 0;
}
خروجی
Enter name: Dennis Ritchie
Your name is Dennis.
حتی اگر رشته ورودی Dennis Ritchie در خود برنامه نوشته شود، باز هم فقط “Dennis” در متغیر name ذخیره میشود. چون بعد از Dennis، یک فاصله وجود دارد.
خواندن یک خط متن
می توانید از تابع ()fgets برای خواندن یک خط رشته و از تابع ()puts برای نمایش رشته استفاده کنید.
مثال ۲: ()fgets و ()puts
#include
int main()
{
char name[30];
printf(“Enter name: “);
fgets(name, sizeof(name), stdin); // حواندن رشته
printf(“Name: “);
puts(name); // نمایش رشته
return 0;
}
خروجی
Enter name: Tom Hanks
Name: Tom Hanks
در اینجا از تابع ()fgets برای خواندن رشته وارد شده توسط کاربر استفاده شده است.
fgets(name, sizeof(name), stdlin); // خواندن رشته
(sizeof(name برابر با ۳۰ می باشد، بنابراین حداکثر ۳۰ کاراکتر از ورودی به اندازه رشته name می خواند.
برای چاپ رشته از (puts(name استفاده شده است.
نکته: تابع ()gets نیز برای گرفتن ورودی از کاربر است اما از استاندارد زبان C حذف شده است. چون ()gets امکان ورود تعداد کاراکتر دلخواه را فراهم می کند، در نتیجه ممکن است بافر سرریز شود.
ارسال رشته به تابع
رشته ها را می توانید مشابه آرایه ها به تابع ارسال کنید.
مثال ۳: ارسال رشته به تابع
#include
void displayString(char str[]);
int main()
{
char str[50];
printf(“Enter string: “);
fgets(str, sizeof(str), stdin);
displayString(str); // ارسال رشته به تابع
return 0;
}
void displayString(char str[])
{
printf(“String Output: “);
puts(str);
}
رشته ها و اشاره گرها
مانند آرایه ها، نام های رشته نیز می توانند به اشاره گرها تبدیل شوند. بنابراین می توانید از اشاره گرها برای دستکاری عناصر رشته نیز استفاده کنید. توصیه می کنیم قبل از بررسی این مثال، آموزش آرایه ها و اشاره گرها در برنامه نویسی C را مرور کنید.
مثال ۴: رشته ها و اشاره گرها
#include
int main(void) {
char name[] = “Harry Potter”;
printf(“%c”, *name); // Output: H
printf(“%c”, *(name+1)); // Output: a
printf(“%c”, *(name+7)); // Output: o
char *namePtr;
namePtr = name;
printf(“%c”, *namePtr); // Output: H
printf(“%c”, *(namePtr+1)); // Output: a
printf(“%c”, *(namePtr+7)); // Output: o
}
توابع رشته ای پر کاربرد
- ()strlen- طول رشته را محاسبه می کند.
- ()strcpy – یک رشته را در یک رشته دیگر کپی می کند.
- ()strcmp – دو رشته را با هم مقایسه می کند.
- ()strcat – دو رشته را به هم متصل می کند.
