Строка в языке C (в литературе, посвященной языку С++, ее часто называют С-строкой (C-string), или строкой в стиле языка С (C-style)) — это массив символов, завершающийся нулем. Рассмотрим пример.
char* p = "asdf"; char s[ ] = "asdf";
P = 9 a s 'd' T 0
s: a s d' T 0
В языке C нет функций-членов, невозможно перегружать функции и нельзя определить оператор (такой как ==) для структур. Вследствие этого для манипулирования строками в стиле языка С необходим набор специальных функций (не членов класса). В стандартных библиотеках языков C и C++ такие функции определены в заголовочном файле .
size_t strlen(const char* s); /* определяет количество символов */
char* strcat(char* si, const char* s2); /* копирует s2 в конец s1 */ int strcmp(const char* si, const char* s2); /* лексикографическое
сравнение */
char* strcpy(char* si,const char* s2); /* копирует s2 в s1 */
char* strchr(const char *s, int c); /* копирует c в s */
char* strstr(const char *si, const char *s2); /* находит s2 в s1 */ char* strncpy(char*, const char*, size_t n); /* сравнивает n
символов */
char* strncat(char*, const char, size_t n); /* strcat с n
символами */
int strncmp(const char*, const char*, size_t n); /* strcmp с n
символами */
Это не полный список функций для работы со строками, но он содержит самые полезные и широко используемые функции. Кратко проиллюстрируем их применение. Iwl Мы можем сравнивать строки. Оператор проверки равенства (==) сравнивает значения указателей; стандартная библиотечная функция strcmp() сравнивает значения C-строк.
const char* si = "asdf"; const char* s2 = "asdf";
if (si==s2) { /* ссылаются ли указатели si и s2 на один и тот же массив? */
/* (обычно это нежелательно) */
}
if (strcmp(si,s2)==0) { /* хранят ли строки si и s2 одни и те же
символы? */
}
Функция strcmp() может дать три разных ответа. При заданных выше значениях si и s2 функция strcmp(si,s2) вернет нуль, что означает полное совпадение. Если строка si предшествует строке s2 в соответствии с лексикографическим порядком, то она вернет отрицательное число, и если строка si следует за строкой s2 в лексикографическом порядке, то она вернет положительное число. Термин лексикографический (lexicographical) означает “как в словаре.” Рассмотрим пример. strcmp("dog","dog")==0
strcmp("ape","dodo")<0 /* "ape" предшествует "dodo" в словаре */ strcmp("pig","cow")>0 /* "pig" следует после "cow" в словаре */
Результат сравнения указателей si==s2 не обязательно равен 0 (false). Механизм реализации языка может использовать для хранения всех строковых литералов одну и ту же область памяти, поэтому можем получить ответ 1 (true). Обычно функция strcmp() хорошо справляется со сравнением С-строк.
Длину С-строки можно найти с помощью функции strlen(). int lgt = strlen(si);
Обратите внимание на то, что функция strlen() подсчитывает символы, не учитывая завершающий нуль. В данном случае strlen(si)==4, а строка "asdf" занимает в памяти пять байтов. Эта небольшая разница является источником многих ошибок при подсчетах.
Мы можем копировать одну С-строку (включая завершающий нуль) в другую. strcpy(si,s2); /* копируем символы из s2 в si */
Программист должен сам гарантировать, что целевая строка (массив) имеет достаточный размер, чтобы в ней поместились символы исходной строки.
Функции strncpy(), strncat() и strncmp() являются версиями функций strcpy(), strcat() и strcmp(), учитывающими не больше n символов, где параметр n задается как третий аргумент. Обратите внимание на то, что если в исходной строке больше n символов, то функция strncpy() не будет копировать завершающий нуль, поэтому результат копирования не будет корректной С-строкой.
Функции strchr() и strstr() находят свой второй аргумент в строке, являющейся их первым аргументом, и возвращают указатель на первый символ совпадения. Как и функция find(), они выполняют поиск символа в строке слева направо. Удивительно, как много можно сделать с этими простыми функциями и как легко при этом допустить незаметные ошибки. Рассмотрим простую задачу: конкатенировать имя пользователя с его адресом, поместив между ними символ @. С помощью класса std::string это можно сделать так:
string s = id + '@' + addr;
С помощью стандартных функций для работы с С-строками этот код можно написать следующим образом:
char* cat(const char* id, const char* addr)
{
int sz = strlen(id)+strlen(addr)+2;
char* res = (char*) malloc(sz);
strcpy(res,id);
res[strlen(id)+1] = '@';
strcpy(res+strlen(id)+2,addr);
res[sz-1]=0;
return res;
}
Правильный ли ответ мы получили? Кто вызовет функцию free() для строки, которую вернула функция cat() ?
^ ПОПРОБУЙТЕ
Протестируйте функцию cat(). Почему в первой инструкции мы добавляем число 2? Мы сделали глупую ошибку в функции cat(), найдите и устраните ее. Мы “забыли” прокомментировать код. Добавьте соответствующие комментарии, предполагая, что читатель знает стандартные функции для работы с С-строками.
Опубликовал katy
May 01 2015 10:57:17 ·
0 Комментариев ·
2213 Прочтений ·
• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •
Комментарии
Нет комментариев.
Добавить комментарий
Рейтинги
Рейтинг доступен только для пользователей.
Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.
Нет данных для оценки.
Гость
Вы не зарегистрированны? Нажмите здесь для регистрации.