آشنایی با کلاس std::string و تفاوت آن با آرایه کاراکتری
درک تفاوت `cin >>` و `getline` برای خواندن رشته
پیادهسازی الگوریتم شمارش کلمات با دو روش ساده و دقیق
تبدیل حروف کوچک به بزرگ و برعکس با استفاده از کدهای اسکی
یافتن تعداد تکرار یک زیررشته در رشته اصلی و استخراج اعداد از رشته
کلاس std::string چیست؟
کلاس std::string (یا به اختصار string با using namespace std;) یک نوع دادهی مدرن در C++ برای کار با متن است که در کتابخانهی <string> قرار دارد. این کلاس برخلاف آرایهی کاراکتری C-style، خودش طول رشته را مدیریت میکند و نیازی به کاراکتر \0 دستی ندارد.
ویژگیهای مهم std::string:
تغییرپذیر: میتوان کاراکترهای آن را با اندیس تغییر داد (s[2] = 'X')
پویا: طول آن میتواند در زمان اجرا تغییر کند
امن: خطر Buffer Overflow ندارد
عملگرهای ساده: با =, +, ==, <, > کار میکند
تعریف و مقداردهی string
برای استفاده از string باید <string> را include کنید. در عصر جدید C++ این هدر معمولاً بهصورت ضمنی توسط <iostream> هم include میشود، اما برای اطمینان همیشه صریح بنویسید.
روشهای مختلف تعریفcpp
$خروجی برنامه
Hello World
*****
Hello World
در حال باز کردن ویرایشگر…
تفاوت char و string
در جزوه اصلی یک خطای مفهومی وجود دارد: نوشته شده char ch = "z" که با خط قرمز مشخص شده. در C++ نوع char فقط برای ذخیرهی یک کاراکتر با کوتیشن تکی 'z' مناسب است. برای ذخیرهی رشتهی چندکاراکتری (حتی یک حرف مثل "z") باید از string استفاده کنید.
نسخه اشتباه جزوه
کد دارای باگcpp
نسخه اصلاحشده و استاندارد
کد صحیحcpp
تفاوت cin و getline
دو راه اصلی برای خواندن ورودی رشتهای وجود دارد:
cin >> s: تا رسیدن به اولین فاصله (یا Tab یا Enter) میخواند. بنابراین فقط یک کلمه را میگیرد.
getline(cin, s): کل خط (شامل فاصلهها) را تا رسیدن به Enter میخواند.
مثلاً اگر ورودی "Salam Donya" باشد:
cin >> s فقط "Salam" را میگیرد.
getline(cin, s) کل "Salam Donya" را میگیرد.
ویژگی
cin >> s
getline(cin, s)
خواندن فاصله
✗
✓
خواندن Enter
✗
✓ (پایان رشته)
مناسب برای
کلمه
جمله/خط کامل
خواندن جمله با getline
برای خواندن جملهای که شامل فاصله است، حتماً از getline استفاده کنید.
خواندن کل خط بهجای یک کلمهcpp
$خروجی برنامه
Enter a sentence: Hello C++ World
You typed: Hello C++ World
نکته مهم: پاکسازی بافر با cin.ignore
اگر قبل از getline از cin >> استفاده کرده باشید، کاراکتر Enter در بافر باقی میماند و getline آن را بهعنوان ورودی خالی میخواند! راهحل: بین cin >> و getline یک دستور cin.ignore() قرار دهید تا Enter اضافی پاک شود.
main.cppcpp
طول رشته با .length()
متد length() (یا size()) تعداد کاراکترهای رشته را برمیگرداند. این متد نوع size_t (بدون علامت) برمیگرداند، پس در مقایسه با int مراقب باشید.
بدست آوردن تعداد کاراکترهای رشتهcpp
$خروجی برنامه
Length = 3
First char = A
Last char = i
در حال باز کردن ویرایشگر…
دسترسی و تغییر کاراکترها
میتوان با عملگر [] به هر کاراکتر دسترسی پیدا کرد یا آن را تغییر داد. این یکی از مزایای string نسبت به ثابت بودن برخی رشتهها در زبانهای دیگر است.
string مانند آرایه اندیسدهی میشودcpp
$خروجی برنامه
Abi
در حال باز کردن ویرایشگر…
مثال ۱: شمارش کلمات (روش ساده)
ایدهی ساده: تعداد کلمات برابر تعداد فاصلهها + ۱ است. این روش فرض میکند بین کلمات دقیقاً یک فاصله است و جمله با فاصله شروع یا تمام نمیشود.
تعداد فاصلهها + ۱cpp
$خروجی برنامه
Enter a sentence: I love C++
Word count = 3
مثال ۲: شمارش کلمات (روش دقیق)
اگر جمله دارای فاصلههای متوالی باشد (مثلاً "Hello World" با دو فاصله)، روش ساده اشتباه جواب میدهد. روش دقیق: یک کلمه را زمانی میشماریم که یک فاصله با کاراکتر غیرفاصلهی بعد از آن همراه شود (یعنی شروع یک کلمهی جدید). اگر رشته با فاصله شروع نشده باشد، کلمهی اول را هم اضافه میکنیم.
نادیده گرفتن فاصلههای متوالیcpp
$خروجی برنامه
Enter a sentence: Hello beautiful world
Word count = 3
فلوچارت شمارش کلمات دقیق
گامهای شمارش کلمات با نادیده گرفتن فاصلههای متوالی:
flow.svg
مثال ۳: تبدیل حروف کوچک به بزرگ
در جدول اسکی، کد هر حرف کوچک انگلیسی دقیقاً ۳۲ واحد بیشتر از حرف بزرگ آن است. مثلاً 'a' = 97 و 'A' = 65. پس برای تبدیل کوچک به بزرگ، کافی است ۳۲ از کد اسکی کم کنیم. همچنین میتوان از تابع آماده toupper در <cctype> استفاده کرد.
تفاوت کد اسکی حروف ۳۲ استcpp
$خروجی برنامه
Enter text: Hello World 123
HELLO WORLD 123
مثال ۴: شمارش تعداد تکرار یک زیررشته
میخواهیم تعداد دفعاتی که رشتهی S2 در S1 ظاهر شده را بشماریم. روش: در هر موقعیت ممکن i، چک میکنیم آیا زیررشتهی شروعشده از i با طول S2.length() برابر با S2 است یا نه. برای جلوگیری از خطای unsigned، حتماً نوعها را به int تبدیل کنید.
جستجوی s2 در s1cpp
$خروجی برنامه
Enter S1: aabcdcabd
Enter S2: ab
2
در حال باز کردن ویرایشگر…
فلوچارت جستجوی زیررشته
گامهای شمارش تعداد تکرار S2 در S1:
flow.svg
مثال ۵: استخراج و جمع دو عدد از رشته
میخواهیم رشتهای مثل "123+456" را بخوانیم و مجموع دو عدد ۱۲۳ و ۴۵۶ یعنی ۵۷۹ را چاپ کنیم. روش: ابتدا اندیس علامت + را پیدا میکنیم، سپس ارقام قبل و بعد از آن را به عدد تبدیل میکنیم. فرمول تبدیل کاراکتر به رقم: s[i] - '0' (یا s[i] - 48).
نکته: عنوان این مسئله در جزوه «مجموع ارقام» نوشته شده، اما کد واقعاً مجموع دو عدد را محاسبه میکند، یک تناقض در جزوه اصلی که ما آن را اصلاح کردیم.
رشتهی "123+456" → عدد ۵۷۹cpp
$خروجی برنامه
Enter expression (e.g. 123+456): 123+456
Sum = 579
در حال باز کردن ویرایشگر…
روش مدرنتر: استفاده از s.find
بهجای حلقهی دستی برای پیدا کردن علامت +، میتوانید از متد آماده s.find('+') استفاده کنید. این متد اندیس اولین وقوع را برمیگرداند یا اگر پیدا نشد، مقدار string::npos را برمیگرداند:
main.cppcpp
این روش خواناتر و کمخطاتر از حلقهی دستی است.
هشدار: نوع size_t بدون علامت است
تابع s.length() نوع size_t (بدون علامت) برمیگرداند. اگر بنویسید s.length() - 2 و طول رشته کمتر از ۲ باشد، نتیجه یک عدد بسیار بزرگ و مثبت میشود (نه منفی!). برای جلوگیری از این خطای خاموش، همیشه به int تبدیل کنید: (int)s.length() - 2.
این یکی از رایجترین منابع باگ در برنامههای C++ مبتنی بر رشته است.
1#include<iostream>2usingnamespace std;3intmain(){4char ch ="z";// ✗ char فقط یک کاراکتر با کوتیشن تکی میگیرد5 cout << ch;6return0;7}
1#include<iostream>2#include<string>3usingnamespace std;4intmain(){5char ch ='z';// ✓ تک کاراکتر با کوتیشن تکی6 string s ="z";// ✓ رشته با کوتیشن دوتایی7 cout << ch <<' '<< s;8return0;9}
1#include<iostream>2#include<string>3usingnamespace std;45intmain(){6 string str ="Ali";7 str[1]='b';// تغییر حرف دوم8 cout << str << endl;// Abi9return0;10}
1#include<iostream>2#include<string>3usingnamespace std;45intmain(){6 string str;7 cout <<"Enter a sentence: ";8getline(cin, str);910int k =0;11for(int i =0; i <(int)str.length(); i++){12if(str[i]==' ') k++;13}14 cout <<"Word count = "<< k +1<< endl;15return0;16}
1#include<iostream>2#include<string>3usingnamespace std;45intmain(){6 string str;7 cout <<"Enter a sentence: ";8getline(cin, str);910int k =0;11for(int i =0; i <(int)str.length()-1; i++){12if(str[i]==' '&& str[i +1]!=' ')13 k++;// شروع یک کلمهی جدید14}15if(!str.empty()&& str[0]!=' ')16 k++;// کلمهی اول1718 cout <<"Word count = "<< k << endl;19return0;20}
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.
شروع/پایانپردازشتصمیمورودی/خروجی
1#include<iostream>2#include<string>3usingnamespace std;45intmain(){6 string str;7 cout <<"Enter text: ";8getline(cin, str);910for(int i =0; i <(int)str.length(); i++){11if(str[i]>='a'&& str[i]<='z')12 str[i]-=32;// تبدیل به حرف بزرگ13}14 cout << str << endl;15return0;16}