CS Atlas GATE 2027
PDS course
0 / 103 complete

PDS/Phase 1 · Programming in C

Lesson 1.5.3 · Item 27 of 103

Strings: char arrays, '\0', read-only string literals, strlen vs sizeof, string functions and tracing string code

Read at your own pace. Try the questions before opening the answers.

On this page

0 · Recall Warm-up

Answer from memory first. Answers are in the Answer Vault at the bottom.

  • What is the address of a[i][j] in int a[R][C] starting at B? from Lesson 1.5.2
  • int *p and int *q point into one array, 2016 and 2040. What is q − p? from Lesson 1.4.3
  • What lifetime does a static local variable have? from Lesson 1.3.2

1 · The Hook

🎣

A name like “Asha” or a message like “Train 12951 is late” is a row of characters. Different texts have different lengths, and a function that prints or copies text must know where it stops. C’s answer is a marker character at the end, like the full stop at the end of a sentence.

2 · Predict First

🤔

What does this print?

char s[] = "GATE";
printf("%u %u\n", sizeof(s), strlen(s));

Make a guess in your head. The answer opens Section 3.

3 · Core Concept

💡

Predict First — the answer

Output

5 4

The array holds G, A, T, E and an invisible end marker '\0': 5 bytes. strlen counts the characters before the marker: 4.

Strings and the null character '\0'

A string in C is a char array whose characters are followed by the null character '\0' (value 0). Every string function stops at the first '\0'. The string literal "GATE" therefore occupies 5 bytes.

char arrays vs string literals

  • char s[] = "GATE"; creates a 5-byte array and copies the text into it. You may change it: s[0] = 'L';
  • char *p = "GATE"; makes p point to the string literal itself, which is stored in read-only memory. p[0] = 'L'; is undefined behavior (often a crash).
  • char s[4] = "GATE"; is legal C but leaves no room for '\0', so s is not a string; printing it reads past the end.

strlen vs sizeof

char s[] = "GATE";
char t[10] = "hi";
printf("%u %u %u %u %u\n", sizeof(s), strlen(s), sizeof(t), strlen(t), sizeof("abc"));

Output

5 4 10 2 4

sizeof gives the array’s size in bytes (including '\0' and any unused space). strlen counts characters up to, not including, '\0'. For a char *p, sizeof p is the pointer size (4), whatever it points to.

Printing and the standard functions

printf("%s", p) prints characters from p up to '\0'. With #include <string.h>:

FunctionDoes
strlen(s)number of characters before \0
strcpy(d, s)copies s (with \0) into d; d must be big enough
strcat(d, s)appends s to the end of d
strcmp(a, b)compares in dictionary order of character codes: negative, 0, or positive
strncpy(d, s, n)copies at most n characters (may not add \0)
char a[20] = "data";
char b[] = "base";
strcat(a, b);
printf("%s %u\n", a, strlen(a));
strcpy(b, "abc");
printf("%s %d %d %d\n", b, strcmp("abc", "abd") < 0, strcmp(b, "abc"), strcmp("b", "a") > 0);

Output

database 8
abc 1 0 1

Never compare strings with ==: that compares addresses.

Walking a string with a pointer

Most string code moves a pointer until it reaches '\0':

int mylen(const char *s)
{
    const char *p = s;
    while (*p != '\0')
        p++;
    return (int)(p - s);
}

int main(void)
{
    printf("%d %d\n", mylen("pointer"), mylen(""));
    return 0;
}

Output

7 0

p + k is a shorter string

If p points into a string, p + k is the string that starts k characters later; printing it with %s prints the tail. *p + 1 is the character code of *p plus 1 (a different character), not the next character.

char s[] = "abcdef";
char *p = s;
p += 2;
*p = 'X';
printf("%s %s %c %c\n", s, p + 1, *p + 1, *(p - 1));

Output

abXdef def Y b

4 · Visual

Diagram: 'G' · [0] · 3000 · 'A' · [1] · 3001 · 'T' · [2] · 3002 · 'E' · [3] · 3003 · '2' · [4] · 3004 · '0' · [5] · 3005 · '2' · [6] · 3006 · '7' · [7] · 3007 · '\0' · [8] · 3008 · s · s + 4

char s[] = "GATE2027": 9 bytes (8 characters + the null character). printf("%s", s + 4) prints 2027.

char s[] = "stack";   reversing in place with two indices

  index:   0   1   2   3   4   5
  start:  's' 't' 'a' 'c' 'k' '\0'     i=0 j=4  swap -> 'k' ... 's'
  step1:  'k' 't' 'a' 'c' 's' '\0'     i=1 j=3  swap
  step2:  'k' 'c' 'a' 't' 's' '\0'     i=2 j=2  stop (i < j fails)
  result: "kcats"            ('\0' never moves)

The null character stays at the end; only the characters before it are rearranged.

5 · Worked Examples

Example 1 Easy

What does this print?

char s[] = "GATE2027";
char *p = s + 4;
printf("%s %c %u\n", p, *(s + 1), strlen(p));

Solution

p = s + 4 is the tail "2027". *(s + 1) is 'A'. strlen(p) = 4.

Output

2027 A 4

Example 2 Medium

What does this print?

char s[] = "stack";
int i = 0, j = (int)strlen(s) - 1;
while (i < j) {
    char t = s[i];
    s[i] = s[j];
    s[j] = t;
    i++;
    j--;
}
printf("%s\n", s);

Solution

See the trace in the Visual section.

Output

kcats

Example 3 GATE

What does this print?

char c[] = "PDS2027";
char *p = c;
printf("%s\n", p + p[2] - p[0]);

Solution

p[2] is 'S' (83) and p[0] is 'P' (80): the difference is 3. p + 3 points at "2027". (Character codes of capital letters are consecutive.)

Output

2027

6 · GATE Traps

⚠️

  • A string needs one extra byte for '\0': char s[4] = "GATE" is not a string.
  • Writing into a string literal through a char * is undefined behavior; a char array copy is writable.
  • sizeof counts the whole array (including \0 and unused space); strlen stops before \0.
  • sizeof of a char * is the pointer size, not the text length.
  • Compare strings with strcmp, not ==.
  • *p + 1 changes the character code; *(p + 1) is the next character.

8 · Memory Hook

🧠

“A string is a sentence that ends with a full stop you cannot see.” Every string function reads until it hits the \0 full stop; forget it and they keep reading into someone else’s memory.

9 · Connect the Dots

Lesson 1.5.1 gave rows of one type; strings are rows of chars with an end marker. Real records mix types: a student has a roll number (int), a grade (char) and a name (string). Next lesson answers: how can one variable bundle values of different types under one name?

10 · Self-Test

GATE format. Try every question before opening the vault.

Q1MCQ1 markOutput

What does this print?

char s[] = "GATE2027";
char *p = s + 4;
printf("%s %c %u\n", p, *(s + 1), strlen(p));
  • (A) GATE A 8
  • (B) 2027 A 5
  • (C) 2027 G 4
  • (D) 2027 A 4

Q2NAT1 marksizeof

What is sizeof("PDS")?

Numerical answer: ________

Q3MCQ1 markLiterals

Which line has undefined behavior?

  • (A) char s[] = "hi"; s[0] = 'H';
  • (B) char s[10] = "hi"; s[5] = 'x';
  • (C) char *p = "hi"; p[0] = 'H';
  • (D) char *p = "hi"; p = "ho";

Q4MCQ2 marksOutput

What does this print?

char s[] = "ABCDE";
char *p = s, *q = s + strlen(s) - 1;
while (p < q) {
    *p = *p + 1;
    p++;
    q--;
}
printf("%s\n", s);
  • (A) BCCDE
  • (B) ABCDE
  • (C) BCDDE
  • (D) BCDEF

Q5MSQ2 marksStrings

Which are true for char t[10] = "hi";?

  • (A) strlen(t) is 2
  • (B) sizeof(t) is 10
  • (C) t[2] is '\0'
  • (D) t == "hi" is true

11 · Rule Card

  • String = chars + '\0'; "abc" takes 4 bytes.
  • char s[] = "…" writable copy; char *p = "…" points to a read-only literal.
  • strlen counts before \0; sizeof counts the whole array (or 4 for a pointer).
  • strcpy, strcat, strcmp (0, 0, >0), strncpy in string.h; compare with strcmp, not ==.
  • %s prints from a pointer up to \0; p + k prints the tail.
  • *p + 1 ≠ *(p + 1).

12 · Concept Ledger

Unlocked in this lesson. From here on, these terms may be used.

stringnull character '\0'string literal (read-only)char arraystrlenstrcpystrcatstrcmpstrncpy%s

13 · Answer Vault

Answer Vault

Try the questions first. Open when you are ready to check.

Recall Warm-up

  • B + (i·C + j)·4 (row-major, 4-byte ints).
  • 6 elements.
  • The whole run of the program.

Self-Test

Q1 Answer: (D)1 mark

p starts at index 4; s + 1 is 'A'; strlen("2027") = 4.

Output

2027 A 4
  • (A) is wrong: p points into the middle.
  • (B) is wrong: strlen does not count \0.
  • (C) is wrong: *(s + 1) is the second character.

Re-read: Lesson 1.5.3 — Strings: char arrays, '\0', read-only string literals, strlen vs sizeof, string functions and tracing string code

Q2 Answer: 41 mark

3 characters + \0 = 4.

Re-read: Lesson 1.5.3 — Strings: char arrays, '\0', read-only string literals, strlen vs sizeof, string functions and tracing string code

Q3 Answer: (C)1 mark

p points to a read-only string literal.

  • (A) is wrong: s is a writable copy.
  • (B) is wrong: Index 5 is inside the 10-byte array.
  • (D) is wrong: Re-pointing p is fine.

Re-read: Lesson 1.5.3 — Strings: char arrays, '\0', read-only string literals, strlen vs sizeof, string functions and tracing string code

Q4 Answer: (A)2 marks

p and q meet in the middle: only indices 0 and 1 are increased (A→B, B→C) before p = 2 = q stops the loop.

Output

BCCDE
  • (B) is wrong: Two characters change.
  • (C) is wrong: Index 2 is never changed.
  • (D) is wrong: Only the first half changes.

Re-read: Lesson 1.5.3 — Strings: char arrays, '\0', read-only string literals, strlen vs sizeof, string functions and tracing string code

Q5 Answer: (A) (B) (C)2 marks

== compares addresses, which differ.

  • (D) is wrong: Use strcmp to compare contents.

Re-read: Lesson 1.5.3 — Strings: char arrays, '\0', read-only string literals, strlen vs sizeof, string functions and tracing string code

Ready for the next idea?

Mark this item complete when you’ve finished reading and working through it.