Глиф Учебники

Как сравнить строки: strcmp, а не ==

Справочник · C · 2 минуты чтения

Строки сравнивает функция strcmp из string.h. Она возвращает 0, если строки одинаковые:

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

int main(void) {
    char answer[50];
    scanf("%49s", answer);
    if (strcmp(answer, "yes") == 0) {
        printf("Согласие получено\n");
    } else {
        printf("Ответ: %s\n", answer);
    }
    return 0;
}
Ввод
yes
Вывод
Согласие получено

Почему == не работает

Имя массива — это адрес его первого символа, строка в кавычках — тоже адрес. answer == "yes" сравнивает два адреса, а не буквы. Массив answer и строка "yes" лежат в разных местах памяти, поэтому сравнение ложно, даже если введено ровно yes. gcc предупреждает:

Текст
warning: comparison with string literal results in unspecified behavior [-Waddress]

Так же нельзя скопировать строку через =: для этого есть strcpy.

Что возвращает strcmp

Сравнение идёт по кодам символов слева направо, до первого различия. Сами числа, кроме нуля, не определены стандартом — это может быть −1 и 1, а может разница кодов. Поэтому проверяют знак: < 0, > 0, == 0, но не == 1 или == -1.

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

int main(void) {
    printf("%d\n", strcmp("apple", "banana") < 0);
    printf("%d\n", strcmp("apple", "app") > 0);
    printf("%d\n", strcmp("Zoo", "apple") < 0);
    return 0;
}
Вывод
1
1
1

Другие варианты сравнения

Только начало строки — strncmp(a, b, n) сравнивает не больше n первых символов. Проверка, начинается ли строка с http: strncmp(s, "http", 4) == 0.

Без учёта регистра (чтобы Yes и yes считались одинаковыми) — в стандарте C такой функции нет. В Linux и macOS есть strcasecmp из <strings.h>, в Windows — _stricmp из <string.h>. Переносимый способ — перевести обе строки в один регистр функцией tolower из ctype.h и сравнить.

Один символ — это не строка, его сравнивают через ==: if (s[0] == 'y'). Одинарные кавычки — символ, двойные — строка.

Подводные камни