JS
C

JavaScript to C

10 lessons

Progress0%
1Variables & Types2Functions3Arrays & Pointers4Objects → Structs5Memory Management6Preprocessor & Headers7String Handling in Depth8Enums and Bitwise Operations9Bit-Fields and Unions10Multi-File Projects and Linking
All Mirror Courses
JS
C
String Handling in Depth
MirrorLesson 7 of 10
Lesson 7

String Handling in Depth

C strings as char arrays: manipulation, safety, and common functions

Introduction

In this lesson, you'll learn about string handling in depth in C. Coming from JavaScript, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.

Mirror Card
JS
From JavaScript:

In JavaScript, you're familiar with c strings as char arrays: manipulation, safety, and common functions.

C
In C:

C has its own approach to c strings as char arrays: manipulation, safety, and common functions, which we'll explore step by step.

The C Way

Let's see how C handles this concept. Here's a typical example:

C
C Example
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void) {
    char s[] = "Hello, World!";  // mutable copy

    // Length
    size_t len = strlen(s);   // 13 — O(n), not a property!

    // Comparison (never use ==)
    if (strcmp(s, "Hello, World!") == 0) { /* equal */ }
    strncmp(s, "Hello", 5);   // compare first 5 chars

    // Copy
    char dst[50];
    strcpy(dst, s);           // unsafe if dst too small!
    strncpy(dst, s, 49);      // safer — limit chars
    dst[49] = '\0';           // strncpy may not null-terminate!

    // Concatenation
    char buf[50] = "Hello, ";
    strcat(buf, "Alice!");    // unsafe
    strncat(buf, "Alice!", 49 - strlen(buf)); // safer

    // Search
    char *pos = strchr(s, 'W');    // pointer to first 'W'
    char *sub = strstr(s, "World"); // pointer to "World"

    // Formatted string
    char msg[100];
    snprintf(msg, sizeof(msg), "Value: %d", 42); // safe printf to buffer

    // Duplicate (heap alloc)
    char *copy = strdup(s);   // must free()!
    free(copy);

    return 0;
}

Comparing to JavaScript

Here's how you might have written similar code in JavaScript:

JS
JavaScript (What you know)
const s = "Hello, World!";
s.length;               // 13
s.toUpperCase();        // "HELLO, WORLD!"
s.includes("World");    // true
s.indexOf("o");         // 4
s.slice(7, 12);         // "World"
s.replace("World","C"); // "Hello, C!"
const parts = s.split(", "); // ["Hello","World!"]

// Concatenation
const greeting = "Hello, " + "Alice!";

// Formatting
const msg = `Value: ${42}`;
Mirror Card
JS
From JavaScript:

You may be used to different syntax or behavior.

C
In C:

C strings are null-terminated char arrays — strlen() is O(n), not a property

Mirror Card
JS
From JavaScript:

You may be used to different syntax or behavior.

C
In C:

strcmp() for equality — never use == (compares pointers, not content)

Mirror Card
JS
From JavaScript:

You may be used to different syntax or behavior.

C
In C:

strcpy/strcat are unsafe; prefer strncpy/strncat/snprintf with size limits

Mirror Card
JS
From JavaScript:

You may be used to different syntax or behavior.

C
In C:

strdup() allocates a heap copy — must be freed with free()

Mirror Card
JS
From JavaScript:

You may be used to different syntax or behavior.

C
In C:

String literals ("hello") are read-only; char[] copies are mutable

Step-by-Step Breakdown

1. Strings are char Arrays

C strings are arrays of chars ending with a null byte '\0'. The string length is the number of chars before '\0'.

JS
JavaScript
const s = "Hello"; s.length; // 5
C
C
char s[] = "Hello";  // {'H','e','l','l','o','\0'}
size_t len = strlen(s); // 5 — counts to \0
Common Pitfall
char *s = "Hello" is a pointer to a read-only literal. char s[] = "Hello" is a mutable copy. Modifying a literal is undefined behavior.

2. Comparison and Search

Always use strcmp() to compare strings. == compares memory addresses, which will almost always differ even for identical content.

JS
JavaScript
s === "hello"
s.includes("ell")
s.indexOf("l")
C
C
strcmp(s, "hello") == 0   // equality
strstr(s, "ell") != NULL  // contains
strchr(s, 'l')            // first char
Common Pitfall
if (s == "hello") is almost always wrong in C — it compares pointers.

3. Safe Copying and Formatting

Use snprintf instead of sprintf for safe formatted strings. Use strncat/strncpy with size checks to prevent buffer overflows.

JS
JavaScript
const msg = `Value: ${n}`;
C
C
char buf[100];
snprintf(buf, sizeof(buf), "Value: %d", n);
// sizeof(buf) limits output — never overflows
Rule of Thumb
Prefer snprintf over sprintf; prefer strncat with (sizeof(dst) - strlen(dst) - 1) as limit.

4. strdup and Memory

strdup() creates a heap-allocated copy. It's convenient but requires a matching free(). Prefer stack buffers when size is known.

JS
JavaScript
const copy = s.slice(); // GC handles memory
C
C
char *copy = strdup(original);
if (copy == NULL) { /* malloc failed */ }
// ... use copy ...
free(copy);   // MUST free to avoid leak

Common Mistakes

When coming from JavaScript, developers often make these mistakes:

  • C strings are null-terminated char arrays — strlen() is O(n), not a property
  • strcmp() for equality — never use == (compares pointers, not content)
  • strcpy/strcat are unsafe; prefer strncpy/strncat/snprintf with size limits
Common Pitfall
Don't assume C works exactly like JavaScript. While the concepts may be similar, the syntax and behavior can differ significantly.

Key Takeaways

  • strcmp() for equality; strstr()/strchr() for searching — never use == on strings
  • snprintf(buf, sizeof(buf), fmt, ...) is the safe way to build strings
  • strncpy/strncat with size limits prevent buffer overflows
  • strdup() heap-allocates a copy — always free() it when done
Rule of Thumb
The best way to learn is by doing. Try rewriting some of your JavaScript code in C to practice these concepts.
PreviousNext