950.47K
Category: programmingprogramming

Строки. Строковый литерал

1.

Строки

2.

Строковый литерал
Строка (строковый литерал) является разновидностью одномерного массива. Любая строка в Си
должна заканчиваться нуль-терминатором (ASCIIZ-формат), поэтому при объявлении строки
необходимо предусмотреть для него место.
char str[7] = {‘s’,’t’,’r’,’o’,’k’,’a’,’\0’};
char str[7] = “stroka”;
char str[] = “stroka”;
char *str = “stroka”;
char *str = {‘s’,’t’,’r’,’o’,’k’,’a’,’\0’}; // неверно!!!! только
строка в двойных кавычках может быть проинициализирована при объявлении
указателя.
char q = "A"; // некорректный код!!!

3.

Строковый литерал
Длина строки и размер массива символов – это разные вещи. Массив может состоять из 250 байт, а
строка, записанная в этом массиве, может иметь длину в 16 символов.
В языке Си нет встроенного строкового типа данных, как в других языках программирования,
поэтому вся работа со строками в языке Си является работой с массивами (символов). Тем не менее
существует стандартная библиотека функций для работ со строками <string.h>. .

4.

Инициализация строки
Еще один способ записать в массив строку – считать ее с клавиатуры:
char str[250];
scanf("%s", str);
gets(str);
char str[250];
scanf_s("%s", str, 250);
gets_s(str, sizeof(str));
Функция scanf считывает символы до первого пробела или конца строки (что встретится раньше).
Функция gets считывает строку целиком вместе со всеми пробелами.
Числовой аргумент в качестве дополнительного параметра функций scanf_s и gets_s – отличие
функции с суффиксом _s от ее «небезопасной» версии (без суффикса) – максимальное количество
символов, которое функция может считать (записать). Данный параметр позволяет отследить выход
за границы массива (не оставляя это на усмотрение программиста).
Таким образом компания Microsoft попыталась исправить ситуацию с уязвимостью кода к т.н.
атакам переполнения буфера (buffer overflow attacks), - когда злоумышленник имеет возможность
записать в память за пределами отведенного массива вредоносный код.

5.

Инициализация строки
char str[250];
scan("%s", str);
gets(str);
char str[250];
scanf_s("%s", str, 250);
gets_s(str, sizeof(str));
При этом, если количество считанных символов больше указанного максимального размера, то
функции scanf_s и gets_s ведут себя по-разному. Функция scanf_s весь считанный
фрагмент строки просто выбрасывает, а в массив ничего не записывает. Функция gets_s
завершает работу программы с ошибкой. Если это поведение нас не устраивает, мы можем в
спецификаторе функции scanf_s указать ширину поля, тогда она будет считывать ровно указанное
количество символов (или меньше).
Подобные нестандартные функции для работы с вводом/выводом могут не поддерживаться в
зависимости от версии студии и, безусловно, рушат идею портабельности программ на Си.

6.

Инициализация строки

7.

Стандартные функции для работы со строками
strlen(char* str);
Возвращает длину строки в байтах в массиве str
strcpy(char* strDst, char* strSrc);
Копирует строку из strSrc в strDst, включая нулевой маркер. Возвращает указатель
на начало строки strDst
stpcpy(char* strDst, char* strSrc);
Копирует строку из strSrc в strDst, включая нулевой маркер. Возвращает указатель
на конец строки strDst
stpdup(char* strSrc);
Выделяет память и копирует туда содержимое строки strSrc. Возвращает указатель
на начало строки-копии или NULL, если выделение памяти завершилось неудачно.

8.

Стандартные функции для работы со строками
errno_t strcpy_s(char* strDst, size_t num, const char* strSrc);
Копирует строку из strSrc в strDst. Переменная num содержит размер буфера
strDst. Если копируемое значение плюс нулевой маркер больше num, функция
возвращает код ошибки. Если все прошло успешно, функция возвращает 0.
errno_t strncpy_s(char *strDst, size_t num,
const char *strSrc, size_t count);
То же, что и strcpy_s, но только копирует не более count символов строки из strSrc в
strDst, дописывая в конец нулевой маркер.

9.

Стандартные функции для работы со строками
errno_t strcat_s(char* strDst, size_t num, const char* strSrc);
char* strcat(char* strDst, char* strSrc);
Дописывает strSrc в конец строки strDst. Является функцией конкатенации строк.
errno_t strncat_s(char *strDst, size_t num,
const char *strSrc, size_t count);
char* strncat(char* strDst, char* strSrc, size_t count);
Дописывает count первых символов строки strSrc в конец строки strDst.

10.

Стандартные функции для работы со строками
int strcmp(const char *str1, const char *str2);
Сравнивает лексикографически строки str1 и str2 с учетом различия прописных и строчных
символов. Если строки полностью совпадают, возвращает 0. Лексикографическое
сравнение осуществляется до первого несовпадения, и если символ первой строки в
упорядоченном по алфавиту словаре встречается раньше, чем соответствующий символ
второй строки – возвращает отрицательное значение, иначе – положительное.
int stricmp(const char *str1, const char *str2);
То же, но без учета различия прописных и строчных букв.
int strncmp(const char *str1, const char *str2, size_t count);
int strnicmp(const char *str1, const char *str2, size_t count);
То же, но только для первых count символов.

11.

Стандартные функции для работы со строками
char* strchr(char *str, int ch);
Возвращает указатель на первое вхождение символа ch в строку str или NULL, если
вхождений не найдено.
char* strrchr(char *str, int ch);
Возвращает указатель на последнее вхождение символа ch в строку str или NULL.
char* strset(char *str, int ch);
Заполняет строку str символом ch .
char* strnset(char *str, int ch, size_t count);
Заполняет первые count позиций строки str символом ch .

12.

Стандартные функции для работы со строками
char* strstr(char *str, const char *substr);
Возвращает указатель на первое вхождение подстроки substr в строку str или NULL.
char* strpbrk(char *str, const char *control);
Возвращает указатель на первое вхождение любого символа из строки control в строку
str или NULL, если вхождений не найдено.
char* strtok(char *str, const char *control);
Возвращает указатель на выделенную лексему строки str или NULL. Под лексемой
понимается фрагмент строки, ограниченный любыми из символов строки control.
Чтобы разбить строку на лексемы, необходимо вызвать функцию с указателем на строку
str и получить указатель на первую лексему, последующие вызовы производить с
параметром NULL вместо указателя на строку (пока возвращаемое значение не NULL)

13.

Стандартные функции для работы со строками
char* strlwr(char *str);
Преобразует символы строки к нижнему регистру.
char* strupr(char *str); Преобразует символы строки к верхнему регистру.
char* strrev(char *str);
Меняет порядок следования символов строки на противоположный.
int strspn(const char *str, const char *control);
Возвращает длину сегмента строки str,состоящего только из символов управляющей
строки control. Длина отсчитывается от начала строки str.
int strcspn(const char *str, const char *control);
Возвращает длину сегмента строки str,состоящего только из символов, не входящих в
управляющую строку control. Длина отсчитывается от начала строки str.

14.

char string1[] = "The quick brown dog jumps over the lazy fox";
char string2[] = "The QUICK brown dog jumps over the lazy fox";
int main( void )
{
char tmp[20];
int result;
printf( "Compare strings:\n
%s\n
%s\n\n", string1,
string2 );
result = strcmp( string1, string2 );
if( result > 0 )
strcpy_s( tmp, sizeof(tmp), "greater than" );
else if( result < 0 )
strcpy_s( tmp, sizeof(tmp), "less than" );
else
strcpy_s( tmp, sizeof(tmp), "equal to" );
printf( "
strcmp:
String 1 is %s string 2\n", tmp );
}

15.

void main()
удаление части строки, заключенной в []
{ char *ss;
int i,j,k,n;
scanf("%d",&k);
ss=(char *)malloc(k);
printf("введите строку символов ");
fflush(stdin);
// чистка входного буфера
gets(ss);
printf("\nИсходная строка символов : %s",ss);
j=-1;
// позиция открывающей скобки '[' в строке
for(i=0;*(ss+i);i++)
// цикл прохода по строке до ее конца
{ if (*(ss+i)=='[')
// скобка найдена
{ j=i;
while(*(ss+ ++j)!=']' && *(ss+j)!='[' && *(ss+j));
if (*(ss+j)=='[') i=j-1; // позиция вложенной скобки [ (теперь основной)
else if(*(ss+j++)==']')
// позиция закрывающей скобки
{ n=i;
while(1) if(!(*(ss+n++)=*(ss+j++))) break; // сжатие строки
i--;
}
}
}
printf("\nCжатая строка символов : %s",ss);
}

16.

main()
замена местами последнего и предпоследнего слов
{ int kk,k,n;
char *s,*s1,t;
scanf("%d",&n);
s=(char*)malloc(n);
// выделение памяти без инициализации
s1=(char*)calloc(n,1);
// выделение памяти с инициализацией
if(!s||!s1) return 0;
fflush(stdin);
gets(s);
k=0;
while(*(s+k)) k++;
// переход в конец строки. k – позиция ‘\0’
while(*(s+k)!=' ') k--;
// позиция пробела перед последним словом
k--;
while(*(s+k)!=' ') k--;
// позиция пробела перед предпоследним словом
kk=++k;
// запоминаем позицию первого символа этого слова
n=0;
// перезапись в строку s1 предпоследнего слова
while(*(s+k)!=' ') *(s1+n++)=*(s+k++);
k++;
// запись последнего слова на предпоследнее
while(*(s+k)) *(s+kk++)=*(s+k++);
*(s+kk++)=' ';
// вставка пробела после слова
n=0;
// дозапись слова из строки s1
while(*(s+kk++)=*(s1+n++));
printf("%s",s);
free(s);
free(s1); }
// освобождение памяти
English     Русский Rules