Рекомендації для обробки рядків
Стисло нагадаємо деякі особливості обробки рядків.
1. Визначення символьного масиву фіксованого розміру:
char Array [25];
Не можна розмір масиву задавати за допомогою змінної, тобто буде помилкою визначення (якщо N – непрепроцесорний ідентифікатор):
char Array [N]
2. Визначення динамічного масиву:
char *p;
int N = 25;
р = (char*) malloc(N);
3. Звернення до елемента масиву:
вирази Аrrау[0] і * Array – еквівалентні. Також еквівалентні вирази:
Array[i] *(Array+i) *(i+Array), i[Array]
Для динамічного масиву, адресованого покажчиком р, еквівалентні вирази:
р[0] *р;
p[i] *(p+i) *(i+p), i[p]
4. Перехід до сусіднього (i+1)-го елементу динамічного масиву:
наступні вирази еквівалентні: p[i+1], p++[i] *(p++ +i)
Невірно: Array++[i] – ім'я масиву є константа, за визначенням її не можна змінювати.
5. Варіанти перебору елементів масиву.
int i ;
for (i = 0; i < 25; i++) {Array[i]. . . }
for (i = 0; i < 25; i++) {* (Array+i) . . . }
for (i = 0; i < 25; i++) {* (p+i) . . . }
for (i = 0; i < 25; i++) {p[i]. . . }
Небезпечний варіант (можна забути початок масиву):
for (i = 0; i < 25; i++)
{ *p++….}
6. Рядки в мові Сі "розміщуються" в символьних масивах. Ознакою закінчення рядка служить '\0'.
Якщо визначено масив char string[25]= "це рядок";
то в масиві string[ ] завдовжки 25 байтів буде розміщений рядок завдовжки в 11 байтів і string[10]= = '\0'.
Рядки можуть бути задані в програмі і так:
char *ps = "рядок"; /* Довжина рядка 7 байтів;
ps[6] == '\0'; *(ра+6)== '\0' */
char str [ ] = "це рядок"; /* Рядок і масив однакової довжини */
7. Для введення рядків (які набирають на клавіатурі) зручно використовувати функцію char* gets(char* s), яка розміщує введену послідовність символів в область пам'яті, що адресується покажчиком s. При цьому ознака кінця введення '\n', що додається у вхідний потік при натисненні клавіші <Enter>, функція gets( ) замінює ознакою кінця рядка '\0'.
Використання для введення рядків функції scanf("%s"...) не дозволяє вводити послідовність символів, в яких містяться пропуски або узагальнені пробільні символи. Введення за специфікацією %s виконується до найближчого пропуску.
8. Обчислити довжину (len) рядка, що знаходиться в масиві string або що адресується покажчиком char * string; можна так:
int len;
for (len=0; *(*string+len)!='\0'; len ++) ;
Ще більш зручно застосовувати функції для роботи з рядками із стандартної бібліотеки. Вони описані в заголовному файлі string.h. Наприклад, для визначення довжини рядка використовуйте функцію з прототипом unsigned strlen(char *str). (Повертає довжину рядка без урахування символу, що завершує рядок '\0'.)
9. Копіювати рядок з масиву string або з рядка, що адресується покажчиком char * string, в новий масив, що адресується покажчиком char * s, можна таким чином:
int j;
char *s; s = (char *)malloc(len);
for (j=0; j <= len; j++)
*(s+j)=*(string+j);
тут len – довжина початкового рядка.
Варіант, який зміщує покажчик з початку області пам'яті:
char *а; а = (char *)malloc(len5);
for (; *a++=*s++;);
10. Функції з параметрами-рядками:
1) застосування покажчиків
int length (const char *s) /* const – захист від зміни фактичного параметра */
int i;
{ for (i=0; *( s +і)!='\0'; i++)
/* Навіть вираз *(s++) не змінює "настройку" параметра на зовнішній масив */
return i; /* Довжина рядка */
}
2) застосування масиву
int length (char а[ ]) /*а – є const за синтаксисом масива */
{ int i=0;
while (а[i++] != '\0');
return i-1; /* Довжина (рядка)*/
}