Lesson 1 — Two Ways to Hold Text

← Module home · Lesson 1 of 4 · Lesson 2 — Measuring, indexing →

In this lesson you will learn


1. The atom: char

A char holds one character — written in single quotes:

char grade = 'A';
char digit = '7';        // a character, not the number 7
char newline = '\n';     // an escape character — one char, special meaning

The key fact: '7' is a character whose meaning is the glyph seven — it is not the number 7. (The conversion story is Lesson 4 §3; for now: chars are tiny whole numbers wearing costumes.)

2. The old way — character arrays (C-strings)

Before classes existed, C++ inherited C’s answer: an array of chars with a marker at the end.

char name1[10] = "Ayesha";       // character array — a C-string
 name1
┌───┬───┬───┬───┬───┬───┬───┬────┬────┬────┐
│ A │ y │ e │ s │ h │ a │\0 │ ?  │ ?  │ ?  │
└───┴───┴───┴───┴───┴───┴───┴────┴────┴────┘
  [0]  [1]  [2]  [3]  [4]  [5]  [6]  (boxes 7-9 unused)

The '\0' — the null terminator — is the official end-of-text marker. Everything after it is ignored. The array is 10 boxes; the string is 6 characters, because the terminator says so.

Everything about C-strings follows from that marker:

Task How it works The catch
Length scan until '\0' the length isn’t stored — it’s discovered each time
Copy strcpy(dst, src) dst must be big enough — no check
Join strcat(dst, src) overflows silently if dst is small — no check
Compare strcmp(a, b) == 0 == compares addresses, not text — the classic trap

That last row is the famous one:

char a[10] = "cat", b[10] = "cat";
if (a == b) { ... }          // compares the ARRAYS' addresses — false, always
if (strcmp(a, b) == 0) { ... }   // compares the TEXT — true

And the underlying danger: strcpy/strcat trust the caller absolutely. Write nine letters into a ten-box array with no terminator room and memory past the array gets overwritten — the same unchecked-bounds world as Arrays Lesson 1 §6, but triggered by text.

3. The modern way — std::string

std::string is a class (your first real meeting with one — Stage E makes classes official) that wraps the character array and manages it:

#include <string>

std::string name = "Ayesha";     // creation

What it fixes, point by point:

Problem with C-strings std::string answer
Length not stored name.length() (or .size()) — instant
Fixed capacity grows and shrinks by itself
Overflow-prone copy/join = and + just work, safely
strcmp for equality ==, <, > compare text directly
Out-of-bounds unchecked .at(i) checks and throws (§ Lesson 3)

And the concepts carry over: a std::string is still, underneath, a row of chars with indices 0..length−1 — every traversal and index skill from Arrays transfers directly. The draw-the-boxes habit applies to "cat" exactly as it did to int arrays.

The conceptual difference in one sentence each:

Course standard: std::string everywhere — C-strings appear here so you can (a) read old code and library signatures (const char* labels in error messages, C library functions), and (b) understand what std::string is managing for you.

4. Creation and initialization

std::string s1;                    // empty — length 0
std::string s2 = "hello";          // from a literal
std::string s3("hello");           // same thing, constructor syntax
std::string s4 = s2;               // a real copy (independent — change one, other unaffected)
std::string s5(5, 'a');            // "aaaaa" — count, char

s4 = s2 is worth a beat of silence: it copies the text — the array-assignment trap doesn’t exist here. Assignment is honest deep copy.

5. Input — >> and getline

The two readers from I/O Lesson 2–3 now meet their real purpose:

std::string word, line;

std::cin >> word;                  // one WORD: stops at whitespace
std::getline(std::cin, line);      // one LINE: reads spaces, consumes the newline
Input typed cin >> word gets getline(cin, line) gets
Ayesha Khan Ayesha Ayesha Khan
` spaced ` spaced (skips leading ws) ` spaced ` (keeps them)
(empty Enter) waits for a word "" — an empty line

The mixing trap is the practical hazard of combining them — cin >> n; leaves the newline; a following getline reads it as an empty line. The cures (cin.ignore / cin >> ws) are in I/O Lesson 3 §4 and are assumed knowledge from here on.

Which reader when: >> for single words (usernames, codes); getline for anything with spaces (names, sentences, addresses). A name field must always be getline — "Ayesha Khan" is two words.

6. A complete first program

// greet.cpp — creation, input, length
#include <iostream>
#include <string>

int main() {
    std::cout << "First name: ";
    std::string first;
    std::cin >> first;                       // a first name is one word

    std::cin.ignore(1000, '\n');             // clear the newline (mixing trap!)

    std::cout << "Full name: ";
    std::string full;
    std::getline(std::cin, full);            // a full name has spaces

    std::cout << "Hello, " << full << '\n'
              << "(first: " << first
              << ", " << full.length() << " characters in full)\n";
    return 0;
}

Run with Ayesha / Ayesha Khan: prints the greeting and 16 characters in full. (Count them — spaces are characters.)

Practice

Key takeaways

→ Next: Lesson 2 — Measuring, indexing, joining, comparing