Символьная строка, способы ее представления


Урок 13.

Тема: «Указатели и строки»

1. Представление строки.

В Си строка определяется, как набор символов, заканчивающийся символом ‘\0’, заключенная в двойные кавычки (не апострофы)

 

Определить строку можно следующими способами:

1) char CH[10]; // массив из 10-ти символов

2) char STR[ ] = “ABCD” // массив из 5-ти символов, 5-ый ‘\0’ автоматически

3) char strokа [4] = {‘S’,’I’,’C’,’\0’}; // при инициализации списком символьный массив приобретает статус строки, если явно в конце записать символ ‘\0’

4) char *car1 = “строка 1”; // автоматически

5) char *car2 = {“строка 2”}; // прибавляется

6) char *car3 = (“строка 3”); // символ конца строки ’\0’

7) char *car4; // не инициализированный указатель.

 

Явная инициализация строки (2,3,4,5,6) разрешена только при определении.

Во всех случаях CH, STR, stroka, car1, car2, car3, car4 – адреса первого символа строки.

Доступ к элементам строки можно получить двумя способами:

1. [ ] – индексация,

2. * - по адресу.

В Си индексация элементов массива ведется с 0. это соглашение языка становиться очевидным, если учесть, что индекс определяет не номер элемента, а его смещение относительно начала массива.

 

Например, в примере (3) массив stroka состоит из 4 элементов, тогда

stroka [0] = ‘S’, strokа [1] = ‘I’, stroka [2] = ‘C’, stroka [3] = ‘\0’

Доступ к элементам строки:

Для примера (4).

*car – это символ ‘с’ и car [0] - это символ ‘с’

*(car+2) - это символ ‘р’ и car [2]- это символ ‘р’

 

2. Пример программы перебора элементов строки.

//prim5.cpp – чтение элементов строки

#include <stdio.h>

#include <conio.h>

void main()

{

char *str;

cout << “Введите строку символов. \n”;

gets (str); // считывает строку из stdin и записывает адреса str, добавляя символ ‘\0’

while (*str != ‘\0’ ) // пока не конец строки

{

putch(*str);

str++; //Увеличение адреса на одну ячейку типа char

}

putch(‘\n’);

int count = 0;

while (str[count] !=’\0’) // пока не конец строки

{

putch (str [count]);

count ++;

}

putch(‘\n’);

}

 

При вводе строки “Компилятор языка.”

Результат:

Компилятор строки.

Компилятор строки.

В первом while (*str != ‘\0’)

{…

str++;

}

Операторы можно объединить и записывать:

while (*str++ != ‘\0’) {…}

 

3. Снятие игнорирования символов «пробел», «табуляция» для обеспечения ввода строки с пробелами

Если считывать строку в массив символов, то поток ввода закончится на первом встретившемся во вводе пробеле. Например:

char name[30];

cin>>name;

cout<<mane

Если в этой программе ввести предложение «Флаги нужны всем!», то результатом будет одно слово «Флаги».

Чтобы разделители «пробел» и «табуляция» тоже считывались, необходимо отменить игнорирование разделителей и считывать все символы по одному. Для этого необходимо снять флагskipw, установленный по умолчанию, выполнив следующее:

cin>>resetiosflags(ios::skipws);

 

Пример:

void main()

{

char name[30];

cin>>resetiosflags(ios::skipws);

for(int i=0;I<29;i++)

{

cin>>name[i];

if(name[i]==enter) break; //если нажали клавишу Enter, то ввод прекратить

}

name[i]=’\0’;

cout<<name;

}

Если в этой программе ввести предложение «Флаги нужны всем!», то результатом будет «Флаги нужны всем».

 

В приведенном примере снятие флага «Игнорировать разделители в потоке ввода» выполняется в главной функции. Лучше это делать в отдельной функции, а затем вызывать ее на выполнение.

Пример:

#include “stdafx.h”

// функция игнорирования разделителей

void string (char *string)

{

cin>> resetiosflags(ios::skipws);

for(int i=0;I<80;i++)

{

cin>>string[i];

if(string[i]= =10) break; //если нажали клавишу Enter, то ввод прекратить

}

string[i]=’\0’;

}

 

// главная функция

int main (int argc, char* argv[] )

{

char *str1;

str1=new(char);

cout<<”введи строку\n”;

string(str1);

while (str1 !=’\0) // пока не конец строки

{

cout<<*str1;

str1++;

}

cout<<”\n”;

return 0;

}