Cтроки. Обработка строк с завершающим нулём — КиберПедия 

Индивидуальные и групповые автопоилки: для животных. Схемы и конструкции...

Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций...

Cтроки. Обработка строк с завершающим нулём



В самом общем виде строка представляет собой массив символов, т.е. элементы такого массива имеют символьный тип char или wchar_t (char16_t и char32_t используются намного реже). Тем не менее, обработка строк имеет свою специфику, связанную с тем, что количество символов в строке (длина строки) обычно становится известным только после того, как строка уже введена, а различные действия над строкой часто приводят к изменению её длины.

Как уже говорилось, в С++ имеется два основных способа работы со строками, основанных на разных способах их представления в памяти:

1. использование строк с завершающим нулём (С-строк) – способ, доставшийся в наследство от языка С, при котором строка описывается как обычный символьный массив, размер которого определяется исходя из ограничений задачи на максимальный размер вводимого текста;

2. использование типов string и wstring, определённых в стандартной библиотеке С++, не накладывающих ограничений на размер текста; для каких-то задач обработки текстов можно использовать и тип vector<char> (vector<wchar_t>).

В данном разделе рассмотрим строки в стиле языка С. Строка в C – это последовательность символов, заканчивающаяся символом c кодом 0 ('\0') - этот символ кодовой таблицы всегда используется только для служебных целей (не перепутайте с цифрой 0 – её код 48). В памяти строка представлена как массив с элементами символьного типа, при этом завершающий ноль отделяет текст от оставшейся области памяти, выделенной под строку, – память обычно выделяется с избытком. Обратим внимание, что при использовании строк в стиле С вся ответственность за выделение памяти целиком ложится на программиста!

Описание строкрассмотрим на примерах.

char color[16] – создали массив символов без его заполнения.

char color [16] = "blue " – создали массив из 16 элементов, заполнили первые четыре элемента, пятому элементу автоматически присвоится '\0'.

сhar color [] = "blue " – в отличие от предыдущего варианта, размер массива будет подсчитан автоматически как размер строковой константы+1 (у нас 5).

Ввод-вывод строк.При использовании библиотеки iostream для ввода строк рекомендуется использовать функции cin.getline или cin.get. Например:

char s[256]; cin.getline(s, 256); // или cin.get(s,256);

 

Разница между cin.getline и cin.get в том, что cin.get при считывании строки оставляет в буфере клавиатуры символ-ограничитель (по умолчанию это символ перевода строки, которым мы заканчиваем ввод), при этом следующий cin.get (если он есть), прочитает этот ограничитель и без остановки программы введёт пустую строку.



Рекомендуем использовать для ввода cin.getline, чтобы не попасть в эту ловушку.

Обратим внимание, что cin>>s; прочитает символы строки до первого пробела (!) – этот способ можно использовать, если вводимая строка не содержит пробелов.

Вывод строки можно выполнить обычным способом через выходной поток cout, например: cout<<s;

Можно вывести строку и посимвольно с помощью цикла – ведь строка это массив символов. Например: for (i=0; s[i]!=0;i++) cout<<s[i];

Следующий пример – демонстрация того, что строку можно обрабатывать как обычный массив символов, не забывая про завершающий нуль.

Пусть требуется удалить все пробелы из введённой строки текста.

Поскольку удаление каждого символа из массива – длительная операция перемещения всех следующих за ним символов, то возникает вопрос, как сократить число перемещений при удалении всех разбросанных по строке пробелов. Первое решение приходит в голову сразу – использовать вспомогательную строку, в которую переписать все символы, кроме пробелов. Разумеется, потом вспомогательная строка копируется в исходную. Этот вариант реализован в примере 1.7.

 

// Пример 1.7 – удаление пробелов из строки

// с использованием вспомогательной строки

#include <iostream>

using namespace std;

int main()

{

int r=0,i=0; char s[80],s1[80];

cout<<"?"; cin.getline(s,80);

// перепишем в s1 все символы, кроме пробелов

for(i=0;s[i]!=0;i++)

if (s[i]!=' ') s1[r++]=s[i];

s1[r]=0; // нельзя забыть про завершающий нуль

for (i=0;s1[i]!=0;i++) s[i]=s1[i];

s[i]=0; // скопировали s1 обратно в s

cout<<s<<endl; system("pause"); return 0;

}

 

Первый пришедший в голову вариант не всегда самый лучший. Немного подумав, можно представить более эффективный вариант, который удаляет пробелы и без использования вспомогательной строки:

 

// Пример 1.8 – удаление пробелов из строки

// без использования вспомогательной строки

#include <iostream>

using namespace std;

int main()

{

int r=0,i=0; char s[80];



cout<<"?"; cin.getline(s,80);

for (i = 0; s[i] != 0 && s[i] != ' '; i++);// ищем первый пробел

for (int j = i; s[j] != 0; j++) {

if (s[j] != ' ') {

s[i] = s[j];// передвигаем символы внутри строки

i++;

}

}

s[i] = 0;

cout<<s<<endl; system("pause"); return 0;

}

 

Этот вариант можно ускорить только использованием указателей вместо индексов. Далее мы рассмотрим возможности эффективной обработки массивов и строк, связанные с применением указателей.

 






Опора деревянной одностоечной и способы укрепление угловых опор: Опоры ВЛ - конструкции, предназначен­ные для поддерживания проводов на необходимой высоте над землей, водой...

Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов (88‰)...

Кормораздатчик мобильный электрифицированный: схема и процесс работы устройства...

Индивидуальные и групповые автопоилки: для животных. Схемы и конструкции...





© cyberpedia.su 2017 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав

0.008 с.