Кракозябры вместо русских букв в консольной программе на C почти всегда означают, что вызов setlocale либо отсутствует, либо передан неверный параметр, либо кодировка консоли не совпадает с кодировкой исходного файла. Без установки локали стандартная библиотека C работает в минимальном режиме "C", где корректно обрабатываются только символы базовой ASCII-таблицы.
В этой статье разберём, как работает setlocale, какие категории локали существуют, чем отличается поведение функции в Windows и Linux, и почему даже правильный вызов иногда не убирает «иероглифы» в терминале.
Что делает setlocale и как устроен её синтаксис
Функция setlocale объявлена в заголовочном файле <locale.h> и имеет два аргумента: категорию локали и строку с именем локали. Прототип выглядит так:
#include <locale.h>char *setlocale(int category, const char *locale);
Первый аргумент определяет, какую часть локали вы хотите изменить — от формата чисел до правил сравнения строк. Второй аргумент задаёт конкретную локаль: например, "Russian" в Windows или "ru_RU.UTF-8" в Linux. Если передать пустую строку "", будет применена локаль из переменных окружения пользователя — это обычно самый переносимый вариант.
Функция возвращает указатель на строку с именем установленной локали либо NULL, если запрошенная локаль недоступна в системе. Это возвращаемое значение стоит проверять, особенно на Linux, где нужная локаль может быть просто не сгенерирована.
💡Всегда проверяйте возвращаемое значение setlocale: если оно равно NULL, локаль не установилась, и дальнейшие манипуляции с кодировкой бессмысленны.