π§ What are Strings in C?
A string is essentially an array of characters that ends with a special character called the null terminator (\\0).
char name[] = "John"; // Actually stored as: 'J', 'o', 'h', 'n', '\\0'The \\0 character tells C where the string ends.
π Header File for Strings
To perform string operations, you must include the built-in library:
#include <string.h>This gives you access to all standard string functions like strlen(), strcpy(), etc.
π§ Commonly Used String Functions
Letβs break down the most important ones with explanation, syntax, examples, and behind-the-scenes memory ideas.
β
Why do we use * (pointer) in string-related functions :
π Reason:
In C, strings are actually arrays of characters, and arrays are passed to functions as pointers. So:
char *str = "Hello";Here, str is a pointer to the first character of the string.
π Why is Required in Function Declarations?
When you write a function like:
int strlen(char *str);You're telling the compiler:
βοΈ "I'm receiving the address of the first character of a string."
You cannot pass the entire array or string directly by value in C β C always passes arrays by reference, and this is done via pointers (*).
π« Can We Take String Inputs Directly Without Using Pointers?
No, not in function parameters.
For example:
int strlen(char str[]); // β
Valid, but internally same as char *strBoth of these are functionally identical:
int strlen(char str[]);
int strlen(char *str);Because str[] decays to *str (a pointer) in function parameters.
1οΈβ£ strlen() β String Length
π Purpose: Returns the number of characters in a string, excluding the null terminator \\0.
π Syntax:
int strlen(const char *str);β Example:
char name[] = "Apple";
int len = strlen(name); // returns 5π§ How it works:
Starts at index 0, counts until it finds
\\0.
2οΈβ£ strcpy() β String Copy
π Purpose: Copies a string from source to destination.
π Syntax:
char *strcpy(char *dest, const char *src);β Example:
char src[] = "Hello";
char dest[20];
strcpy(dest, src); // dest now contains "Hello"π§ Behind the Scenes:
Copies each character until
\\0.β οΈ Make sure
desthas enough space.
3οΈβ£ strcat() β String Concatenation
π Purpose: Appends (joins) one string to the end of another.
π Syntax:
char *strcat(char *dest, const char *src);β Example:
char a[20] = "Good ";
char b[] = "Morning";
strcat(a, b); // a becomes "Good Morning"π§ It finds the end of a, then starts adding b from there.
β οΈ Important: a must be large enough to hold the combined result.
4οΈβ£ strcmp() β Compare Strings
π Purpose: Compares two strings lexicographically (like dictionary order).
π Syntax:
int strcmp(const char *str1, const char *str2);β Example:
strcmp("apple", "banana"); // returns < 0 (because apple comes before)
strcmp("abc", "abc"); // returns 0
strcmp("zebra", "apple"); // returns > 0π§ It compares each character until:
They mismatch (and returns the difference),
Or both strings end.
β Do not use == to compare strings. That only compares addresses, not content.
5οΈβ£ strrev() β Reverse a String
β Not part of standard C. Available in some compilers like Turbo C.
β Example:
char s[20] = "Hello";
strrev(s); // Now s = "olleH"You can write your own custom function if needed (see below π).
6οΈβ£ strncpy() β Safe String Copy
Similar to strcpy(), but limits the number of characters.
π Syntax:
char *strncpy(char *dest, const char *src, size_t n);β Example:
char s[] = "World";
char d[10];
strncpy(d, s, 3); // Only copies "Wor"7οΈβ£ strncat() β Safe Concatenation
Same idea as strcat() but with character limit.
strncat(dest, src, n);8οΈβ£ strchr() and strrchr() β Character Search
Function | Purpose |
|---|---|
| Finds first occurrence of a char |
| Finds last occurrence of a char |
Example:
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "CodeVeda Platform";
char ch = 'a';
// Find first and last occurrence
char *first = strchr(str, ch);
char *last = strrchr(str, ch);
printf("Original string: %s\\n", str);
if (first != NULL) {
printf("First '%c' found at index: %ld\\n", ch, first - str);
printf("Substring from first '%c': %s\\n", ch, first);
} else {
printf("Character '%c' not found from start.\\n", ch);
}
if (last != NULL) {
printf("Last '%c' found at index: %ld\\n", ch, last - str);
printf("Substring from last '%c': %s\\n", ch, last);
} else {
printf("Character '%c' not found from end.\\n", ch);
}
return 0;
}Original string: CodeVeda Platform
First 'a' found at index: 6
Substring from first 'a': a Platform
Last 'a' found at index: 14
Substring from last 'a': aform9οΈβ£ strstr() β Substring Search
Finds first occurrence of a string inside another string.
#include <stdio.h>
#include <string.h>
int main() {
char text[] = "Hello world";
char *found = strstr(text, "world");
printf("Found string: %s\\n", found);
return 0;
}Found string: worldπ§ͺ Custom String Manipulation Examples
π Reverse a string (manual)
void reverse(char str[]) {
int len = strlen(str);
for(int i = 0; i < len/2; i++) {
char temp = str[i];
str[i] = str[len - 1 - i];
str[len - 1 - i] = temp;
}
}π Difference Between == and strcmp()
char a[] = "cat";
char b[] = "cat";
if (a == b) { // FALSE: compares addresses
}
if (strcmp(a, b) == 0) { // TRUE: compares content
}π§ Common String Pitfalls
β Mistake | π§ Explanation |
|---|---|
Forgetting | In C, strings are arrays of characters terminated by |
Not allocating enough space | If your string doesnβt have space for all characters plus the null terminator, it causes buffer overflows β writing past allocated memory, which can corrupt data or crash the program. Example: |
Using |
|
Not including | String functions like |
β Summary Table
Function | Purpose |
|---|---|
| Find length |
| Copy |
| Append |
| Compare |
| Reverse (non-standard) |
| First char match |
| Substring search |
<div class="infographic-cstring">
<style>
.infographic-cstring {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--code-bg: #1e1e2e;
--code-text: #d4d4e0;
--syn-keyword: #c586c0;
--syn-func: #dcdcaa;
--syn-string: #ce9178;
--syn-comment: #6a9955;
--warn: #b45309;
--warn-soft: #fdf0dc;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
}
.infographic-cstring[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--code-bg: #0d0d14;
--code-text: #d4d4e0;
--warn: #e0a458;
--warn-soft: #3a2c14;
--ok: #5cd6a0;
--ok-soft: #16342a;
}
.infographic-cstring {
box-sizing: border-box;
max-width: 780px;
margin: 0 auto;
background: var(--paper);
color: var(--ink);
font-family: 'Inter', -apple-system, sans-serif;
padding: 0 clamp(1rem, 4vw, 2.25rem) 1.25rem;
}
.infographic-cstring *, .infographic-cstring *::before, .infographic-cstring *::after {
box-sizing: border-box;
}
.infographic-cstring h1 {
font-family: 'Fraunces', Georgia, serif;
font-weight: 600;
font-size: clamp(1.4rem, 3.5vw, 1.9rem);
margin: 1.25rem 0 0.25rem;
}
.infographic-cstring .subhead { color: var(--ink-soft); font-size: 0.85rem; margin-bottom: 1rem; }
.infographic-cstring .chip-row { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 1rem; }
.infographic-cstring .chip {
all: unset;
cursor: pointer;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
font-weight: 600;
padding: 0.42rem 0.85rem;
border-radius: 20px;
border: 1px solid var(--line);
color: var(--ink-soft);
transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.infographic-cstring .chip:hover { border-color: var(--accent); }
.infographic-cstring .chip.is-active { background: var(--accent); border-color: var(--accent); color: #fff; }
.infographic-cstring .code-panel {
background: var(--code-bg);
color: var(--code-text);
border-radius: 8px;
padding: 0.7rem 0.9rem;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
line-height: 1.6;
margin-bottom: 0.9rem;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
max-width: 100%;
}
.infographic-cstring .code-panel .code-line { white-space: pre; display: block; }
.infographic-cstring .syn-keyword { color: var(--syn-keyword); }
.infographic-cstring .syn-func { color: var(--syn-func); }
.infographic-cstring .syn-string { color: var(--syn-string); }
.infographic-cstring .syn-comment { color: var(--syn-comment); }
.infographic-cstring .field-row { display: flex; align-items: center; gap: 0.55rem; flex-wrap: wrap; margin-bottom: 0.7rem; }
.infographic-cstring .field-row label { font-size: 0.82rem; color: var(--ink-soft); }
.infographic-cstring .field-row input[type="text"] {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.88rem;
padding: 0.35rem 0.55rem;
border-radius: 6px;
border: 1px solid var(--line);
background: var(--paper);
color: var(--ink);
width: 12rem;
max-width: 100%;
}
.infographic-cstring .field-row input[type="number"] {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.88rem;
padding: 0.35rem 0.55rem;
border-radius: 6px;
border: 1px solid var(--line);
background: var(--paper);
color: var(--ink);
width: 4rem;
}
.infographic-cstring .field-row input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.infographic-cstring .string-view {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.95rem;
padding: 0.5rem 0.7rem;
background: var(--code-bg);
border-radius: 6px;
margin-bottom: 0.6rem;
overflow-x: auto;
}
.infographic-cstring .string-view .ch {
color: var(--code-text);
padding: 0.05rem 0.1rem;
border-radius: 3px;
}
.infographic-cstring .string-view .ch.is-match {
background: var(--accent);
color: #fff;
font-weight: 700;
}
.infographic-cstring .result-panel {
padding: 0.75rem 1rem;
background: var(--paper-alt);
border-radius: 8px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.85rem;
color: var(--ink);
min-height: 2.4rem;
line-height: 1.5;
}
.infographic-cstring .result-panel.is-warn { background: var(--warn-soft); color: var(--warn); font-family: 'Inter', sans-serif; font-weight: 600; }
.infographic-cstring .result-panel.is-ok-tag { border-left: 3px solid var(--ok); }
.infographic-cstring .tag {
display: inline-block;
font-family: 'Inter', sans-serif;
font-size: 0.72rem;
font-weight: 700;
text-transform: uppercase;
padding: 0.2rem 0.55rem;
border-radius: 20px;
background: var(--ok-soft);
color: var(--ok);
margin-left: 0.5rem;
}
.infographic-cstring .tag.warn { background: var(--warn-soft); color: var(--warn); }
.infographic-cstring .func-panel { display: none; }
.infographic-cstring .func-panel.is-active { display: block; }
.infographic-cstring .takeaway { font-size: 0.82rem; color: var(--ink-soft); margin-top: 1.25rem; border-top: 1px solid var(--line); padding-top: 0.9rem; }
.infographic-cstring .takeaway strong { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
.infographic-cstring * { transition: none !important; }
}
</style>
<h1>π€ C String Functions Playground</h1>
<p class="subhead">Type your own strings β every result below is computed live.</p>
<div class="chip-row" id="fn-tabs">
<button class="chip is-active" data-fn="strlen">strlen</button>
<button class="chip" data-fn="strcpy">strcpy</button>
<button class="chip" data-fn="strcat">strcat</button>
<button class="chip" data-fn="strcmp">strcmp</button>
<button class="chip" data-fn="strrev">strrev</button>
<button class="chip" data-fn="strchr">strchr</button>
<button class="chip" data-fn="strstr">strstr</button>
</div>
<!-- strlen -->
<div class="func-panel is-active" data-fn="strlen">
<div class="code-panel"><span class="code-line"><span class="syn-func">strlen</span>(<span class="syn-string" id="sl-code-str"></span>);</span></div>
<div class="field-row">
<label>str</label><input type="text" id="sl-str" value="Hello World">
</div>
<div class="result-panel" id="sl-result"></div>
</div>
<!-- strcpy -->
<div class="func-panel" data-fn="strcpy">
<div class="code-panel"><span class="code-line"><span class="syn-func">strcpy</span>(dest, <span class="syn-string" id="scp-code-str"></span>);</span></div>
<div class="field-row">
<label>src</label><input type="text" id="scp-src" value="Hello">
<label>dest buffer size</label><input type="number" id="scp-size" value="10" min="1" max="40">
</div>
<div class="result-panel" id="scp-result"></div>
</div>
<!-- strcat -->
<div class="func-panel" data-fn="strcat">
<div class="code-panel"><span class="code-line"><span class="syn-func">strcat</span>(dest, <span class="syn-string" id="sca-code-str"></span>);</span></div>
<div class="field-row">
<label>dest</label><input type="text" id="sca-dest" value="Hello, ">
<label>src</label><input type="text" id="sca-src" value="World!">
</div>
<div class="field-row">
<label>dest buffer size</label><input type="number" id="sca-size" value="20" min="1" max="60">
</div>
<div class="result-panel" id="sca-result"></div>
</div>
<!-- strcmp -->
<div class="func-panel" data-fn="strcmp">
<div class="code-panel"><span class="code-line"><span class="syn-func">strcmp</span>(<span class="syn-string" id="scm-code-str1"></span>, <span class="syn-string" id="scm-code-str2"></span>);</span></div>
<div class="field-row">
<label>str1</label><input type="text" id="scm-str1" value="apple">
<label>str2</label><input type="text" id="scm-str2" value="banana">
</div>
<div class="result-panel" id="scm-result"></div>
</div>
<!-- strrev -->
<div class="func-panel" data-fn="strrev">
<div class="code-panel"><span class="code-line"><span class="syn-func">strrev</span>(<span class="syn-string" id="sr-code-str"></span>); <span class="syn-comment">// non-standard</span></span></div>
<div class="field-row">
<label>str</label><input type="text" id="sr-str" value="Recursion">
</div>
<div class="result-panel" id="sr-result"></div>
</div>
<!-- strchr -->
<div class="func-panel" data-fn="strchr">
<div class="code-panel"><span class="code-line"><span class="syn-func">strchr</span>(<span class="syn-string" id="sc-code-str"></span>, <span class="syn-string" id="sc-code-ch"></span>);</span></div>
<div class="field-row">
<label>str</label><input type="text" id="sc-str" value="programming">
<label>char</label><input type="text" id="sc-ch" value="g" maxlength="1" style="width:3rem;">
</div>
<div class="string-view" id="sc-view"></div>
<div class="result-panel" id="sc-result"></div>
</div>
<!-- strstr -->
<div class="func-panel" data-fn="strstr">
<div class="code-panel"><span class="code-line"><span class="syn-func">strstr</span>(<span class="syn-string" id="ss-code-hay"></span>, <span class="syn-string" id="ss-code-needle"></span>);</span></div>
<div class="field-row">
<label>haystack</label><input type="text" id="ss-hay" value="learning C programming">
<label>needle</label><input type="text" id="ss-needle" value="gram">
</div>
<div class="string-view" id="ss-view"></div>
<div class="result-panel" id="ss-result"></div>
</div>
<p class="takeaway"><strong>All of these live in <string.h></strong> β and all of them (except strrev, which isn't part of the standard) work with null-terminated <code style="font-family:'IBM Plex Mono',monospace;">char*</code> strings, not a length you pass in.</p>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-cstring')
|| document.querySelector('.infographic-cstring');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
function $(sel) { return wrapper.querySelector(sel); }
function esc(s) { return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); }
function q(s) { return '"' + esc(s) + '"'; }
// ---- tabs ----
const tabs = wrapper.querySelectorAll('#fn-tabs .chip');
const panels = wrapper.querySelectorAll('.func-panel');
tabs.forEach(tab => {
tab.addEventListener('click', () => {
tabs.forEach(t => t.classList.remove('is-active'));
tab.classList.add('is-active');
panels.forEach(p => p.classList.toggle('is-active', p.dataset.fn === tab.dataset.fn));
});
});
// ---- strlen ----
function updateStrlen() {
const s = $('#sl-str').value;
$('#sl-code-str').textContent = q(s);
$('#sl-result').innerHTML = 'strlen(' + q(s) + ') = <strong>' + s.length + '</strong>';
}
$('#sl-str').addEventListener('input', updateStrlen);
// ---- strcpy ----
function updateStrcpy() {
const src = $('#scp-src').value;
const size = Math.max(1, parseInt($('#scp-size').value, 10) || 1);
$('#scp-code-str').textContent = q(src);
const needed = src.length + 1; // +1 for null terminator
const res = $('#scp-result');
if (needed > size) {
res.className = 'result-panel is-warn';
res.textContent = 'β οΈ dest[' + size + '] is too small β needs ' + needed + ' bytes (' + src.length + ' chars + \\0). Buffer overflow.';
} else {
res.className = 'result-panel';
res.innerHTML = 'dest now holds ' + q(src) + '<span class="tag">fits (' + needed + '/' + size + ' bytes)</span>';
}
}
$('#scp-src').addEventListener('input', updateStrcpy);
$('#scp-size').addEventListener('input', updateStrcpy);
// ---- strcat ----
function updateStrcat() {
const dest = $('#sca-dest').value;
const src = $('#sca-src').value;
const size = Math.max(1, parseInt($('#sca-size').value, 10) || 1);
$('#sca-code-str').textContent = q(src);
const combined = dest + src;
const needed = combined.length + 1;
const res = $('#sca-result');
if (needed > size) {
res.className = 'result-panel is-warn';
res.textContent = 'β οΈ dest[' + size + '] is too small for the combined string β needs ' + needed + ' bytes. Buffer overflow.';
} else {
res.className = 'result-panel';
res.innerHTML = 'dest now holds ' + q(combined) + '<span class="tag">fits (' + needed + '/' + size + ' bytes)</span>';
}
}
$('#sca-dest').addEventListener('input', updateStrcat);
$('#sca-src').addEventListener('input', updateStrcat);
$('#sca-size').addEventListener('input', updateStrcat);
// ---- strcmp ----
function updateStrcmp() {
const a = $('#scm-str1').value;
const b = $('#scm-str2').value;
$('#scm-code-str1').textContent = q(a);
$('#scm-code-str2').textContent = q(b);
let result = 0;
const len = Math.min(a.length, b.length);
let i = 0;
for (; i < len; i++) {
if (a.charCodeAt(i) !== b.charCodeAt(i)) { result = a.charCodeAt(i) - b.charCodeAt(i); break; }
}
if (result === 0 && i === len) result = a.length - b.length;
const res = $('#scm-result');
let verdict;
if (result === 0) verdict = 'str1 and str2 are equal';
else if (result < 0) verdict = 'str1 comes before str2';
else verdict = 'str1 comes after str2';
res.className = 'result-panel';
res.innerHTML = 'strcmp(' + q(a) + ', ' + q(b) + ') = <strong>' + result + '</strong><br>' + verdict;
}
$('#scm-str1').addEventListener('input', updateStrcmp);
$('#scm-str2').addEventListener('input', updateStrcmp);
// ---- strrev ----
function updateStrrev() {
const s = $('#sr-str').value;
$('#sr-code-str').textContent = q(s);
const rev = s.split('').reverse().join('');
$('#sr-result').innerHTML = 'strrev(' + q(s) + ') = <strong>' + q(rev) + '</strong>';
}
$('#sr-str').addEventListener('input', updateStrrev);
// ---- strchr ----
function updateStrchr() {
const s = $('#sc-str').value;
const ch = $('#sc-ch').value.slice(0, 1);
$('#sc-code-str').textContent = q(s);
$('#sc-code-ch').textContent = ch ? "'" + esc(ch) + "'" : "'\\0'";
const view = $('#sc-view');
const idx = ch ? s.indexOf(ch) : -1;
view.innerHTML = s.split('').map((c, i) =>
'<span class="ch' + (i === idx ? ' is-match' : '') + '">' + esc(c === ' ' ? '\u00b7' : c) + '</span>'
).join('');
const res = $('#sc-result');
if (idx === -1) {
res.className = 'result-panel';
res.textContent = "strchr didn't find '" + ch + "' β returns NULL.";
} else {
res.className = 'result-panel';
res.innerHTML = "strchr found '" + esc(ch) + "' at index <strong>" + idx + '</strong> β returns a pointer to that position.';
}
}
$('#sc-str').addEventListener('input', updateStrchr);
$('#sc-ch').addEventListener('input', updateStrchr);
// ---- strstr ----
function updateStrstr() {
const hay = $('#ss-hay').value;
const needle = $('#ss-needle').value;
$('#ss-code-hay').textContent = q(hay);
$('#ss-code-needle').textContent = q(needle);
const view = $('#ss-view');
const idx = needle ? hay.indexOf(needle) : -1;
view.innerHTML = hay.split('').map((c, i) => {
const isMatch = needle && idx !== -1 && i >= idx && i < idx + needle.length;
return '<span class="ch' + (isMatch ? ' is-match' : '') + '">' + esc(c === ' ' ? '\u00b7' : c) + '</span>';
}).join('');
const res = $('#ss-result');
if (!needle) {
res.className = 'result-panel';
res.textContent = 'Type a needle to search for.';
} else if (idx === -1) {
res.className = 'result-panel';
res.textContent = 'strstr found no match β returns NULL.';
} else {
res.className = 'result-panel';
res.innerHTML = 'strstr found ' + q(needle) + ' starting at index <strong>' + idx + '</strong>.';
}
}
$('#ss-hay').addEventListener('input', updateStrstr);
$('#ss-needle').addEventListener('input', updateStrstr);
// ---- init ----
updateStrlen();
updateStrcpy();
updateStrcat();
updateStrcmp();
updateStrrev();
updateStrchr();
updateStrstr();
})();
</script>