شناخت هدر <string.h> و توابع کتابخانهای مدیریت رشته در سبک C
استفاده صحیح از strlen، strcpy، strcat، strcmp
درک ترتیب آرگومانها در strcpy (مقصد، منبع)
پیادهسازی برنامهای برای حذف کاراکتر سمیکالن از رشته
مقایسه کار با char[] در برابر std::string
مقدمهای بر کتابخانه string.h
در زبان C، رشتهها بهصورت آرایهای از کاراکترها که با کاراکتر پوچ \0 (Null Terminator) خاتمه مییابند، ذخیره میشوند. برای مثال رشته "SALAM" در حافظه به این شکل است:
main.cppcpp
کتابخانه <string.h> مجموعهای از توابع آماده برای کار با این رشتهها فراهم میکند. مهمترین آنها عبارتاند از:
strlen(s) → طول رشته
strcpy(dest, src) → کپی رشته
strcat(dest, src) → الحاق رشته
strcmp(s1, s2) → مقایسه دو رشته
در C++ مدرن پیشنهاد میشود از کلاس std::string (هدر <string>) استفاده کنید، اما آشنایی با <string.h> برای درک کدهای قدیمی و سوالات کنکور ضروری است.
تابع strlen — محاسبه طول رشته
تابع strlen(s) تعداد کاراکترهای رشته قبل از کاراکتر \0 را برمیگرداند.
main.cppcpp
توجه: strlen فقط تا رسیدن به اولین \0 را میشمارد. اگر آرایه شما ۱۰۰ خانه داشته باشد اما رشته در خانه پنجم به \0 ختم شود، strlen عدد ۵ را برمیگرداند (نه ۱۰۰).
این تابع محتوای رشته source (منبع) را در destination (مقصد) کپی میکند، شامل کاراکتر \0.
main.cppcpp
نکته مهم: آرگومان اول مقصد و آرگومان دوم منبع است. این ترتیب در بسیاری از کتب و جزوات اشتباه نوشته شده است.
اصلاح توضیح strcpy در جزوه
در جزوه اصلی نوشته شده: «strcpy(ch2,ch1); → کپی کردن ch2 به ch1» که از نظر فنی غلط است. تابع strcpy محتوای آرگومان دوم (منبع) را در آرگومان اول (مقصد) کپی میکند، نه برعکس.
نسخه اشتباه جزوه
کد دارای باگcpp
نسخه اصلاحشده و استاندارد
کد صحیحcpp
مثال strcpy و strcat
کپی و الحاق دو رشتهcpp
خروجی برنامه
خروجی
Copy: Hello,
After strcat: Hello, World!
تابع strcmp — مقایسه دو رشته
تابع strcmp(s1, s2) دو رشته را بهصورت لغوی (Lexicographic) مقایسه میکند و مقدار زیر را برمیگرداند:
مقدار بازگشتی
معنی
0
s1 برابر s2
< 0
s1 کوچکتر از s2
> 0
s1 بزرگتر از s2
نکته: برای بررسی برابری دو رشته در سبک C باید بنویسید if (strcmp(s1, s2) == 0). استفاده از if (s1 == s2) در C فقط آدرس دو آرایه را مقایسه میکند که معمولاً مدنظر نیست.
مثال strcmp
مقایسه دو رشته با strcmpcpp
فلوچارت مقایسه دو رشته
flow.svg
برنامه حذف سمیکالن از رشته
برنامهای بنویسید که رشتهای را از ورودی بگیرد و تمام کاراکترهای ; را حذف کرده، بهجای هرکدام یک خط جدید (endl) چاپ کند.
مثال: ورودی hello;world → خروجی:
main.cppcpp
main.cppcpp
خروجی برنامه حذف سمیکالن
خروجی
رشته را وارد کن: hello;world
hello
world
سبک C در برابر C++: مقایسه دو رشته
برنامه مقایسه دو رشته بهصورت کاراکتر به کاراکتر در نسخه جزوه تا طول s1 پیمایش میکرد که اگر s2 کوتاهتر باشد، خطر دسترسی خارج از محدوده وجود دارد. نسخه اصلاحشده از کلاس std::string و عملگر == استفاده میکند که هم سادهتر و هم امنتر است.
نسخه اشتباه جزوه
کد دارای باگcpp
نسخه اصلاحشده و استاندارد
کد صحیحcpp
خطر سرریز بافر (Buffer Overflow)
هنگام استفاده از strcpy و strcat در سبک C، باید مطمئن شوید آرایه مقصد به اندازه کافی بزرگ است. اگر مقصد گنجایش منبع را نداشته باشد، نوشتن ادامه مییابد و دادههای حافظه را خراب میکند که به آن سرریز بافر میگویند.
main.cppcpp
راهحلها:
از نسخههای امن strncpy و strncat با محدودسازی طول استفاده کنید.
یا بهتر، از std::string استفاده کنید که خودش حافظه را مدیریت میکند.
هدر <cstring> بهجای <string.h>
در C++ مدرن بهجای #include <string.h> از #include <cstring> استفاده کنید. تفاوت:
<string.h> — سبک C خالص، توابع در فضای نام سراسری.
<cstring> — سبک C++، توابع در فضای نام std (و گاهی سراسری).
بهترین کار: هم using namespace std; بنویسید و هم از <cstring> استفاده کنید.
برنامهای بنویسید که دو رشته را از ورودی بگیرد و با `strcmp` بررسی کند که آیا برابرند یا خیر. در صورت برابری پیام «برابر» و در غیر این صورت پیام «نابرابر» چاپ شود.
نمایش راهنما
از `if (strcmp(s1, s2) == 0)` استفاده کنید.
02
تمرین•حل کامل دارد
برنامهای بنویسید که نام و نامخانوادگی کاربر را در دو آرایه کاراکتری بگیرد، آنها را بههم بچسباند (با یک فاصله بینشان) و رشته نهایی را بههمراه طول آن چاپ کند.
نمایش راهنما
از `strcat` برای الحاق و `strlen` برای طول استفاده کنید. برای فاصله میتوانید ابتدا `strcat(full, " ")` را فراخوانی کنید.
03
تمرین•حل کامل دارد
برنامهای بنویسید که رشتهای را بگیرد و تعداد تکرار یک کاراکتر مشخص (مثلاً `'a'`) را در آن بشمارد.
نمایش راهنما
با حلقه `for` روی کاراکترها پیمایش کنید و با شمارنده افزایشی کار کنید.
04
تمرین•حل کامل دارد
همان برنامه حذف سمیکالن را با استفاده از `std::string` و `getline` بازنویسی کنید تا ورودی میتواند شامل فاصله هم باشد.
نمایش راهنما
از `getline(cin, s)` برای خواندن خط کامل استفاده کنید و با حلقه for پیمایش کنید.
// نکات-کلیدی۶
01رشتههای سبک C آرایههایی از کاراکتر با پایاندهنده `\0` هستند و توابع مدیریت آن در `<string.h>` یا `<cstring>` قرار دارند.
02تابع `strlen` طول واقعی رشته (تا `\0`) را برمیگرداند، نه اندازه آرایه را.
03در `strcpy(dest, src)` آرگومان اول مقصد و دوم منبع است؛ توضیح معکوس در برخی جزوات اشتباه است.
04برای مقایسه برابری در سبک C از `strcmp(s1, s2) == 0` استفاده کنید؛ در C++ مدرن با `std::string` از `s1 == s2`.
05در استفاده از `strcpy` و `strcat` همیشه ظرفیت آرایه مقصد را چک کنید تا سرریز بافر رخ ندهد.
06در پروژههای جدید C++ ترجیح بر استفاده از `std::string` است چون حافظه را خودکار مدیریت میکند.
./project-arraysپروژهٔ پایانی این دسته
آمارگیر کلاس
کار کامل با آرایه، مرتبسازی، جستجو و هیستوگرام
آخرین درس این دسته را تمام کردی — وقت آن است که همهچیز را یکجا به محک بزنی. برنامهای بنویس که نمرهٔ n دانشآموز (حداکثر ۱۰۰ نفر) را در آرایه بخواند و گزارش کامل بدهد: بیشینه، کمینه، میانگین، نمرات مرتبشده، رتبهٔ یک نمرهٔ مشخص (جستجو) و هیستوگرام توزیع نمرات بهازای هر بازهٔ دو نمرهای (۰-۱، ۲-۳، …).
⏱ ۹۰ دقیقه تا ۲ ساعت۶ نیازمندی — هر کدام به یک درس لینک است
نام درس، موضوع یا کلمه کلیدی را بنویسید و با Enter به آن بروید
[S][A][L][A][M][\0]
char ch[]="Hello";cout <<strlen(ch);// خروجی: 5
1#include<iostream>2#include<cstring>// معادل مدرن string.h3usingnamespace std;45intmain(){6char ch[100];7 cout <<"رشته را وارد کن: ";8 cin >> ch;9 cout <<"طول رشته: "<<strlen(ch)<< endl;10return0;11}12
char src[]="Hello";char dest[100];strcpy(dest, src);// dest حالا برابر "Hello" است
1// توضیح اشتباه در جزوه:2// strcpy(ch2, ch1); → "کپی کردن ch2 به ch1" ✗34// اگر همین اشتباه در کد هم رخ دهد:5char a[10]="ABC";6char b[10]="XYZ";7strcpy(a, b);// واقعاً چه اتفاقی میافتد؟8// طبق توضیح غلط: b به a کپی میشود؟ خیر!9// طبق واقعیت C++: محتوای b در a کپی میشود، یعنی a="XYZ"10// پس توضیح «کپی ch2 به ch1» معنای معکوس میدهد.
1// توضیح صحیح:2// strcpy(destination, source);3// محتوای منبع (آرگومان دوم) در مقصد (آرگومان اول) کپی میشود.45char src[10]="ABC";6char dest[10];7strcpy(dest, src);// محتوای src در dest کپی میشود8// حالا dest = "ABC" و src دستنخورده باقی میماند.
1#include<iostream>2#include<cstring>3usingnamespace std;45intmain(){6char s1[100], s2[100];7 cout <<"s1: ";8 cin >> s1;9 cout <<"s2: ";10 cin >> s2;1112int result =strcmp(s1, s2);13if(result ==0)14 cout <<"برابرند\n";15elseif(result <0)16 cout <<"s1 قبل از s2 میآید\n";17else18 cout <<"s1 بعد از s2 میآید\n";1920return0;21}22
flow.svg100%
Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.
شروع/پایانپردازشتصمیمورودی/خروجی
hello
world
1#include<iostream>2#include<cstring>3usingnamespace std;45intmain(){6char ch[100];7 cout <<"رشته را وارد کن: ";8 cin >> ch;910for(int i =0; i <(int)strlen(ch); i++){11if(ch[i]!=';')12 cout << ch[i];13else14 cout << endl;15}16 cout << endl;17return0;18}19
1// نسخه دارای ریسک در جزوه2#include<string>3#include<iostream>4usingnamespace std;5intmain(){6 string s1, s2;7 cin >> s1 >> s2;8// اگر s2 کوتاهتر از s1 باشد، s2[i] ممکن است9// خارج از محدوده باشد (در عمل string امن است اما10// منطق نامعتبر است).11for(int i =0; i <(int)s1.length(); i++){12if(s1[i]== s2[i]) cout <<"^";13else cout <<"1";14}15return0;16}17
1// نسخه اصلاحشده: پیمایش تا کوتاهترین طول2#include<string>3#include<iostream>4usingnamespace std;5intmain(){6 string s1, s2;7 cin >> s1 >> s2;8 size_t mn =min(s1.length(), s2.length());9for(size_t i =0; i < mn; i++){10if(s1[i]== s2[i]) cout <<"^";11else cout <<"1";12}13// نمایش اختلاف طول با ستاره14int diff =(int)s1.length()-(int)s2.length();15if(diff !=0) cout <<" (طولها متفاوت)";16 cout << endl;17return0;18}19
char small[5];strcpy(small,"Hello World");// خطرناک! ۱۲ کاراکتر در ۵ خانه