Строкой (строчкой) в языке Си называется массив типа
char. Элементами маассива являются коды соответствующиx
символов.
Последним элементом массива является 0 — маркер конца строки.
Длиной строки называется количество ее букв, не включая маркер конца строки.
Предполагается, что одна буква кодируется одним элементом типа
char, то есть кодировка содержит не более 255 букв. Программы на
Си могут некорректно работать с современными кодировками типа
UTF-8. Многобайтовые кодировки мы не рассматриваем.
Для хранения строки из n символов нужно выделить как минимум n+1 байт памяти.
Наличие маркера конца строки позволяет при передаче строки в функцию не передавать ее длину. Рассмотрим в качестве примера прототип и возможную реализацию функции вычисления длины строки.
int string_length(const char *s) {
int len = 0;
while(*s++) {
len++;
}
return len;
}
Во-первых, функция получает только адрес начала строки. Во-вторых,
заметим, что если в строке пропущен маркер конца строки, то
результат выполнения этой функции не определен, и ее вызов может
привести к ошибке сегментирования, если цикл while выйдет за
пределы памяти, отведенной операционной системой процессу.
Для вывода строк можно использовать функции семейства printf (printf, fprintf, sprintf и т.п.). В строке формата нужно поставить %s.
const char *str = "This is a string";
printf("The string is: '%s'\n", str);
Для ввода строк есть функция
char *fgets(char *s, int size, FILE *stream);
Параметр size определяет максимальный размер строки, включая маркер конца строки.
Память для хранения строки должна быть выделена заранее.
Функции семейства scanf считывают их входного потока одно слово.
scanf("%s", str); /* ОПАСНО */
Либо с ограничением длины:
scanf("%12s", str); /* Будет записано не более 13 символов, включая 0. */
При работе со строками часто возникают следующие ошибоки.
char *s; не достаточно. Нужно выделить память.)
s1 = s2;. Если после этого изменить строку s2, то изменится и s1. Копировать нужно посимвольно.
Стандартная бибилиотека предоставляет набор функций для работы со строками.
Для работы с нми нужно подключить заголовочный файл #include <strings.h>.
int strcmp(const char *s1, const char *s2);
Возвращает: отрицательное число, если s1 меньше s2, 0, если равны, и положительно число, если s1 больше s2.
int strncmp(const char *s1, const char *s2, size_t n);
char *stpcpy(char *dest, const char *src);
char *strchr(const char *s, int c);
char *strstr(const char *haystack, const char *needle);
Возвращает адрес, где в строке haystack первый раз встречается строка needle. Если needle не встречается, то возвращается значене NULL.
/*
** Чтение длинной строки.
**
** Функция считывает из текущей позиции файла f строчку сколь угодно
** большого размера. Символ перевода строки '\n' копируется в выходную
** строчку, если он был во входном фале.
** Память для хранения выходной строки динамически выделяется.
** Вызывающая функция должна освободить память вызовом free.
**
** Возвращаемое значение:
** адрес строки, если чтение прошло успешно
** NULL, если не удалось прочитать исходную строчку.
*/
char *read_long_string(FILE *f)
{
char buf[1024];
buf[0] = 0;
sprintf(stderr, "This is a prototype!\n");
char *s = fgets(buf, 1024, f);
if(s) {
int len = strlen(s);
char *result = malloc(len + 1);
strcpy(result, s);
return result;
}
return NULL;
}
int main() {
char *s = read_long_string(stdin);
// ....
free(s);
return 0;
}