В C нет строкового типа, но стандартная библиотека C определяет строки для символьных массивов с нулевым символом в конце §7.1.1p1 стандарта C11 Draft
Строка - это непрерывная последовательность символов, оканчивающаяся и включающая первый нулевой символ.
Таблица, показанная OP, верна, что char
, signed char
и unsigned char
все шириной 1 байт. Диапазоны минимальных значений указаны для типов в Стандарте, но без диапазонов абсолютных значений; хотя диапазоны значений в таблице являются общими, они не гарантируются. В частности, нередко char
является типом без знака с диапазоном значений от 0 до 255. Обратите внимание, что для типов со знаком char
стандарт требует только минимального диапазона от -127 до 127. Даже байты должны иметь минимальная 8 битная ширина, но точно 8 бит не указана. Фактические детали - это детали реализации.
%c
и %s
используются в форматированных операциях ввода / вывода; они не имеют прямого отношения к типам, а используются для описания функций, которые следует ожидать типам. Для функций семейства fprintf()
спецификатор преобразования %c
указывает функции ожидать целочисленный аргумент, который будет преобразован в значение unsigned char
и напечатан как символ. Обратите внимание, что кодировка символов не обязательно должна быть ASCII (это еще одна деталь реализации), но это наиболее распространенная в наши дни.
Спецификатор преобразования %s
сообщает функциям fprintf()
ожидать указатель на первый элемент массива символов. Если подходящая точность не указана (например, %5s
для печати не более 5 символов), массив должен быть строкой (то есть заканчиваться нулем).
Для функций семейства fscanf()
директива %c
говорит функции сканировать один или несколько символов на входе (т. е. больше, чем один, когда указана ширина поля, например, %3c
), и ожидать указатель на массив символов, достаточно большой для хранения результатов. Для простого scanf("%c", &some_char)
максимальное количество символов для сканирования составляет 1, а some_char
просто должно быть char
, например, определенным как char some_char;
. Но для чего-то вроде scanf("%5c", five_chars)
, five_chars
должен быть массивом, способным хранить 5 char
с, например, определенным как char five_chars[5];
.
Директива %s
действует аналогично для функций fscanf()
, но без указания максимальной ширины поля fscanf()
будет пытаться сопоставить и сохранить символы до тех пор, пока во входных данных не встретятся пробелы. Функция ожидает указатель на массив символов, способный содержать все совпадающие символы (плюс нулевой терминатор), и по этой причине вы всегда должны указывать максимальную ширину поля, чтобы избежать потенциального переполнения буфера. Также обратите внимание, что директива %s
всегда приводит к тому, что терминатор \0
записывается после сканирования последнего символа. Таким образом, когда хранилище объявлено как char storage[100];
, правильно использовать scanf("%99s", storage);
. Это говорит scanf()
о соответствии не более 99 символов на входе перед записью окончательного \0
, избегая записи после конца массива storage[]
в случае большого ввода.
Более подробная информация о fprintf()
и fscanf()
. Обратите внимание, что fscanf()
, в частности, является сложной функцией, которую сложно использовать правильно.