Unit 3 · Lesson 720 minAcademic review pending

Copying, joining and comparing strings

You cannot assign or compare strings with = and ==. The string library does that work, and an array of pointers holds a list of strings.

Choose explanation

After this lesson

You should be able to

  • Use strcpy, strncpy, strcat and strlen correctly.
  • Compare two strings with strcmp and interpret its return value.
  • Declare an array of pointers to strings and loop over it.
01

Why = and == do not work

A string is an array, and C will not assign one array to another. name2 = name1; does not compile. And if both were pointers, == would compare addresses — asking whether they are the same string in memory, not whether they spell the same thing.

So the library gives you strcpy to copy and strcmp to compare. Both need #include <string.h>.

Copy, then join
#include <string.h>

char a[20] = "Warangal";
char b[20];

strcpy(b, a);              /* b now holds "Warangal"     */
strcat(b, " district");    /* b now "Warangal district"  */

printf("%zu\n", strlen(b));  /* 18 — excludes the \0    */
02

strcmp returns an order, not a yes or no

strcmp(a, b) returns 0 when the strings are equal, a negative number when a comes before b alphabetically, and a positive number when it comes after. So equality is strcmp(a, b) == 0 — reading it as 'if strcmp is true' gets the logic exactly backwards, because 0 means equal and 0 is false.

Because it returns an ordering, strcmp is exactly what a sort needs. Swap the integer comparison in Unit III's selection sort for strcmp(...) < 0 and it sorts names.

Zero means equal; the sign gives the order
if (strcmp(town, "Warangal") == 0)
    printf("Same town\n");

/* Sorting names uses the sign, not just zero */
if (strcmp(names[j], names[smallest]) < 0)
    smallest = j;
03

An array of pointers is a list of strings

const char *days[] = {"Mon", "Tue", "Wed"}; stores three addresses, each pointing at text. The strings may have different lengths, and no space is wasted padding them to a common width — unlike a 2D char array, where every row occupies the same number of bytes.

Mark them const. String literals must not be modified, and const turns an attempt to do so into a compile error rather than a crash at run time.

Three strings of different lengths, no wasted space
const char *days[] = {"Monday", "Tuesday", "Wednesday"};

for (int i = 0; i < 3; i++)
    printf("%d: %s (%zu letters)\n", i, days[i], strlen(days[i]));

Try it yourself

Store five town names, sort them alphabetically, and print the sorted list.

Need a hint?

Use an array of pointers and swap the pointers, not the text.

Check the worked solution

Swapping pointers rather than copying characters is the point of this exercise: each swap moves 8 bytes regardless of how long the town names are, and no destination-size worry arises because nothing is copied. The comparison is strcmp(...) < 0, reusing the selection sort from earlier in this unit with only the comparison changed.

#include <stdio.h>
#include <string.h>
#define SIZE 5

int main(void)
{
    const char *towns[SIZE] = {"Warangal", "Adilabad", "Nizamabad",
                               "Khammam", "Karimnagar"};

    for (int i = 0; i < SIZE - 1; i++) {
        int smallest = i;

        for (int j = i + 1; j < SIZE; j++)
            if (strcmp(towns[j], towns[smallest]) < 0)
                smallest = j;

        if (smallest != i) {
            const char *temp = towns[i];
            towns[i] = towns[smallest];
            towns[smallest] = temp;
        }
    }

    for (int i = 0; i < SIZE; i++)
        printf("%s\n", towns[i]);

    return 0;
}

Quick check

How do you test whether two strings a and b are equal?

Select an answer to check your thinking.

Why this lesson exists

Syllabus mapping

String Library Functions: Assignment and Substrings · String Comparison · Arrays of Pointers

Maps to course outcome CO5.