Exercises — String handling — char arrays, null terminator, strcpy, strcat, strlen, sprintf (dangers)
5.1.20 · D4· Coding › C Programming › String handling — char arrays, null terminator, strcpy, strc
Shuru karne se pehle, ek chhota sa vocabulary piece jo neeche ke code mein milega:
Yeh counting rule baar baar use karoge:
Neeche di gayi picture un do numbers ko ek real array par visible karti hai — dekho kaise red terminator box length bracket ke bahar lekin bytes bracket ke andar baitha hai.

Figure mein notice karo: upar ka black double-arrow exactly 3 visible characters (strlen = 3) ko span karta hai, jabki neeche ka red double-arrow ek box zyada span karta hai — woh extra box '\0' hai. Woh sirf ek extra box hi +1 rule ka poora content hai, aur is page par har exercise aslaan mein usi ka track na khoone ke baare mein hai.
Level 1 — Recognition
(Bas rule ka naam batao. Counting se aage koi code tracing zaroori nahi.)
L1.1
Recall Solution
Word "code" mein 4 characters hain: c o d e. strlen terminator se pehle ke characters count karta hai, isliye yeh 4 return karta hai.
String store karne ke liye use hone wali bytes : bytes c o d e \0. Array ki baaki bytes exist karti hain lekin is string ke liye unused hain.
L1.2
Recall Solution
"Hi!" mein characters hain (H, i, !). Minimum bytes . +1 kabhi mat bhoolna: size 3 ka array '\0' ke liye room nahi dega aur string unterminated ho jaayegi. (Yahi woh array hai jo upar figure mein draw ki gayi hai.)
Level 2 — Application
(Rule ko ek chhoti si computation ya trace par apply karo.)
L2.1
Recall Solution
strcat(a, b) b ko a ke end mein append karta hai. Pehle woh a ko uske '\0' tak walk karta hai (abc ke baad), us '\0' ko overwrite karta hai, phir de aur ek naya '\0' copy karta hai. Result string: "abcde".
strlen("abcde") terminator se pehle ke 5 characters count karta hai ⇒ 5 print karta hai.
Byte check: joined string ko bytes chahiye, aur a 20 bytes ka hai — kaafi room hai, isliye koi overflow nahi.
L2.2
Recall Solution
sprintf formatted text "12345" ko buf mein likhta hai aur '\0' append karta hai. Yeh likhe gaye characters ki count return karta hai, '\0' ko exclude karke — woh 5 hai. Isliye n == 5.
Likhne ke baad, buf mein 1 2 3 4 5 \0 hai, isliye strlen(buf) == 5. Output: 5 5.
Bytes used , isliye buf yahan kaafi bada hai. Lekin note karo: sprintf ne yeh kabhi check nahi kiya — agar number 8+ digits ka hota toh silently overflow ho jaata.
L2.3
Recall Solution
Array: O(79) K(75) \0(0).
n = 0:s[0] = 'O' != '\0'→ true, isliyen1 ho jaata hai.n = 1:s[1] = 'K' != '\0'→ true, isliyen2 ho jaata hai.n = 2:s[2] = '\0'→ false, loop ruk jaati hai.- Return
n =2. Match karta hai:"OK"ki length 2 hai aur 3 bytes occupy karta hai.
Level 3 — Analysis
(Ab tumhe kyun ke baare mein reason karna hoga — bug dhundho, danger count karo.)
L3.1
Recall Solution
Safe nahi hai — buffer overflow. "Robert" mein characters hain (R o b e r t). strcpy saare 6 characters plus '\0' copy karta hai, jisme bytes chahiye. Lekin name sirf 6 bytes ka hai.
Overflow amount 1 byte. Woh ek akela stray '\0' jo name ke end ke ek past likha gaya hai woh Undefined Behaviour in C hai — yeh ek adjacent variable corrupt kar sakta hai, crash kar sakta hai, ya ek machine par silently ignore ho sakta hai aur doosri par fail ho sakta hai. Dekho Buffer Overflow & Memory Safety.
Fix: char name[7]; ya snprintf(name, sizeof name, "%s", "Robert"); (jo "Rober" tak truncate kar dega — koi overflow nahi).
L3.2
Recall Solution
strcat ke liye byte rule: destination ko strlen(dst) + strlen(src) + 1 hold karna chahiye.
strlen(c) = 2("12")strlen("3456") = 4- Needed bytes.
Capacity of
cis 8. Kyunki hai, koi overflow nahi — result"123456"(6 chars +'\0'= 7 bytes) fit ho jaata hai. Yeh exactly 1 spare byte ke margin se safe hai.
L3.3
Recall Solution
Bug sizeof buf hai. store ke andar, buf ek char * parameter hai, array nahi. Ek pointer par sizeof pointer size deta hai — typically 64-bit machine par 8 — chahe real buffer kitna bhi bada ho. Isliye snprintf ko bata diya jaata hai ki buffer 8 bytes ka hai chahe caller ne 100-byte array pass ki ho (unsafe: unnecessarily truncate karta hai) ya 4-byte wali (unsafe: phir bhi overflow hoti hai kyunki 8 > 4 hai). Yeh Arrays vs Pointers decay trap hai.
Fix: size explicitly pass karo:
void store(char *buf, size_t cap) {
snprintf(buf, cap, "%s", "hello");
}(size_t cap yahan bas "ek byte-count" hai, jaisa page ke upar define kiya gaya hai.)
Level 4 — Synthesis
(Kai ideas combine karo; ek chhota sa correct routine design karo.)
L4.1
Recall Solution
snprintf use karo capacity pass karke — ek bounded call hi teeno kaam kar deta hai. (Yaad karo size_t = "ek byte-count", page ke upar define hua hai.)
#include <stdio.h>
#include <stddef.h> // for size_t
// returns chars that WOULD be written (snprintf semantics)
int join3(char *buf, size_t cap, const char *a,
const char *b, const char *c) {
return snprintf(buf, cap, "%s%s%s", a, b, c);
}snprintf kyun aur strcat kyun nahi? snprintf cap leta hai aur guarantee karta hai ki woh zyada se zyada cap bytes total likhega ('\0' including), overflow ki jagah truncate karta hai. Teen strcat calls mein manual size checks chahiye hoti — error-prone hota hai.
Minimum capacity "C" (1) + " is " (4) + "fun" (3) join karne ke liye: total characters , string banti hai "C is fun". Bytes needed 9. char buf[9] exactly kaafi hai.
L4.2
Recall Solution
#include <stddef.h> // for size_t
char *my_strncat_safe(char *dst, size_t cap, const char *src) {
size_t i = 0;
while (i < cap && dst[i] != '\0') i++; // 1) find dst's end, but never run past cap
size_t j = 0;
// 2) leave room for '\0': stop at cap-1
while (i < cap - 1 && src[j] != '\0')
dst[i++] = src[j++];
if (cap > 0) dst[i] = '\0'; // 3) always terminate
return dst;
}Guard 1 (i < cap): original my_strcat dst ke '\0' tak bina kisi upper bound ke scan karta tha — agar dst already corrupt/unterminated tha, toh woh scan khud array se bahar jaa sakta tha. Hum ise cap karte hain.
Guard 2 (i < cap - 1): hum copying ek byte pehle rok dete hain taaki terminator ke liye hamesha space bache. cap - 1 tak likhne se index cap - 1 free rehta hai.
Guard 3 (if (cap > 0) dst[i] = '\0'): guarantee karta hai termination chahe hum truncate kar chuke hon. cap > 0 check dst[-1] likhne se bachata hai jab koi capacity 0 pass kare.
Yahi discipline hai jo snprintf ko safe banati hai: writes ko bound karo, '\0' ke liye room reserve karo, hamesha terminate karo.
Level 5 — Mastery
(Deep reasoning: complexity, degenerate inputs, subtle correctness.)
Pehle, ek notation piece jo yahan use karoge:
L5.1
Recall Solution
Har strcat ko append karne se pehle pehle buf ko uske '\0' tak scan karna hota hai. Iteration par (0-indexed), buf mein pehle se characters hain. End dhundhne ke liye, strcat un characters mein se har ek ko '\0' ke against compare karta hai (sab "not equal") aur phir ek aur comparison terminator ke against karta hai (jo equal hai, scan khatam karta hai). Isliye iteration exactly comparisons leta hai — woh +1 woh final terminator check hai, aur exact count mein ise DROP NAHI KARNA CHAHIYE.
ke liye exact count, comparisons sum karte hue: Isliye ends dhundhne ke liye 10 character-comparisons.
Asymptotic complexity. Exact total par ka sum hai:
Dominant term hai, isliye — upar ke Big-O rule ke anusaar constant aur chhota drop karke — loop hai: parent note se "Shlemiel the painter" quadratic blow-up. (Ek running end-pointer rakhna poore loop ko bana deta.) Exact formula ko asymptotic se alag karne ka point yeh hai ki +1-per-iteration terms hi exact count ko 6 ki jagah 10 banate hain, chahe woh Big-O mein ghayab ho jaate hain.
L5.2
Recall Solution
(a) Empty string "" ek single byte '\0' ke roop mein store hoti hai. strlen dekhta hai e[0] == '\0' immediately aur 0 return karta hai. Length 0 ki ek valid string ko bhi 1 byte chahiye — terminator. Yeh sabse chhoti legal C string hai.
(b) u mein a b c hai bina kisi '\0' ke (initializer ne saari 3 bytes real chars se bhar di). strlen(u) scanning shuru karta hai aur array ke andar koi terminator nahi dhundhta — woh array ke paar neighbouring memory mein padhta rehta hai. Yeh Undefined Behaviour in C hai: returned "length" garbage hai aur scan crash kar sakta hai. u ek valid C string nahi hai.
(c) Size 0 ke saath, snprintf buf mein kuch nahi likhta — '\0' bhi nahi — kyunki ek bhi byte ke liye room nahi hai. Yeh buf ko untouched chhod deta hai lekin phir bhi 2 return karta hai (woh characters ki count jo likhni chahiye thi, "hi"). Isliye snprintf ka size-0 case safe hai: woh overflow karne ki jagah likhne se mana kar deta hai.
Score yourself
Recall Mastery checklist reveal karo
Agar tumne L1–L2 solve kiya toh tum rules jaante ho (length vs bytes, +1).
L3 ka matlab hai tum overflows aur sizeof-pointer trap spot kar sakte ho.
L4 ka matlab hai tum bounded, hamesha-terminating code likh sakte ho.
L5 ka matlab hai tum complexity aur degenerate cases samajhte ho — ek char array aur ek valid string ke beech ka fark, size-0 snprintf, aur quadratic strcat loop.
Koi miss hua? parent note ka woh section dobara padho aur retry karo.
Connections
- Pointers in C — har scan actually array par pointer arithmetic hai.
- Arrays vs Pointers — L3.3 ka
sizeof bufdecay bug. - Buffer Overflow & Memory Safety — har L3 overflow ka consequence.
- Undefined Behaviour in C — L5.2 ka unterminated array.
- printf format specifiers —
sprintf/snprintf%d %s %fshare karte hain. - Time Complexity — L5.1 ka
strcatloop.