Наш магазин на eBay Наш магазин на AliExpress Наш канал в telegram

Строки (AnsiString) и символьные массивы (Char[], Char*) в C++ Builder

  1. Введение
  2. Преобразование типов
  3. Некоторые полезные методы класса AnsiString

Введение

Итак, в С++ Builder строки можно задать тремя разными способами: через специальный класс AnsiString, через массив символов char[] и через указатель на первый символ массива char*:

AnsiString String1="Hello!";
char *String2="Hello!";
char String3[]={'H','e','l','l','o','!','\0'};
char String4[7]={'H','e','l','l','o','!','\0'};

Задание строк String3 и String4 на самом деле эквивалентно, просто если задавать строку так, как у нас задана строка String3, то её обязательно нужно сразу инициализировать, тогда циферку в квадратные скобки за вас вставит компилятор.

Использование класса AnsiString удобно тем, что заданные с его помощью строки являются динамическими и можно особо не париться с их размером. То есть можно писать, например, так:

AnsiString String1;
String1="Hello!";
String1="Hello world!";

И пофигу, что во втором случае строка стала длиннее, пускай Builder сам с этим разбирается.

Для символьных массивов такой фокус не прокатит от слова совсем. Для указателя прокатит, но нужно понимать, что при этом на самом деле не меняется исходный массив, а просто изменяется значение указателя и он начинает указывать на другой существующий массив (который кто-то создал, память под него выделил). При этом старый массив, на который указывал указатель, просто потеряется. Это чревато всякими утечками памяти и тому подобными косяками.

Строки, заданные как массив символов, должны оканчиваться нулём (по-другому их называют нультерминированные). Массив Char-ов может содержать нули, но при этом строкой считается всё, что содержится от начала массива до первого встреченного нулевого символа. Например, можно задать вот такой массив:

char TempStr[]={'H','e','l','l','o',0x0,'w','o','r','l','d','\0'};

Если в этом случае попробовать посчитать длину строки TempStr, то она окажется равной пяти, то есть количеству элементов от начала строки до нультерминатора, без учёта его самого. (Как видите, элементы массива не обязательно писать в кавычках, как символы, можно и напрямую в hex).

Более того, один массив может содержать сразу две строки. Фактически в предыдущем примере так оно и есть. Если мы напишем вот такой код:

char TempStr[]={'H','e','l','l','o',0x0,'w','o','r','l','d','\0'};
Edit1->Text=TempStr;
Edit2->Text=&TempStr[6]; // &TempStr[6] - адрес шестого элемента ('w')

, то в Edit1 получим текст «Hello», а в Edit2 — текст «world».

Ещё одной фишкой является то, что в AnsiString элементы считаются с единицы, а в массивах символов (да и в любых вообще массивах) — с нуля (именно поэтому символ ‘w’ в предыдущем примере шестой, а не седьмой). То есть вот такой код:

char Str[]={'H','e','l','l','o','\0'};
AnsiString AStr="Hello";
Edit1->Text=Str[1];
Edit2->Text=AStr[1];

выведет в поле Edit1 символ ‘e’, а в поле Edit2 символ ‘H’.

Да, кстати, как видите, элементы AnsiString тоже можно получить по индексам, совсем как элементы массива.

Поскольку AnsiString — это класс, то он имеет множество всяких полезных свойств и методов, позволяющих особо не париться с различными операциями над строками. Для массива вместо этого приходится пользоваться специальными библиотечными функциями или писать свои.

Преобразование типов

Как правило, самый частый вопрос, который возникает при работе со строками, — это преобразование типов, когда из AnsiString нужно получить массив Char или наоборот.

Итак, сначала получаем из AnsiString массив Char. Сделать это можно следующим образом:

Вариант 1

AnsiString AStr="Hello";
char Str1[10]={'a','a','a','a','a','a','a','a','a','a'};
 
strcpy(Str1,AStr.c_str()); // копируем в существующий массив
 
Edit1->Text=Str1;

Вариант 2

AnsiString AStr="Hello";
char *Str2; // создаём указатель, который пока ни к чему не привязан
 
Str2 = new char[ Astr.Length() + 1 ]; // создаём новый массив,
                                      // привязываем к нему указатель
strcpy(Str2,AStr.c_str());            // и копируем в этот массив
 
Edit1->Text=Str2;

В первом случае нужно дополнительно проверить, чтобы массив, в который происходит копирование, был достаточного размера. Размер массива должен быть на 1 больше количества символов в строке (1 дополнительный элемент нужен для нультерминатора).

Как делать не нужно!

Вариант 2

AnsiString AStr="Hello";
char *Str2 = AStr.c_str();

В хэлповнике по Builder-у написано, что функция c_str() возвращает временный указатель на внутренний буфер строки в объекте AnsiString, который действителен только на время выполнения выражения, в котором он используется.

Для того, чтобы преобразовать массив char-ов в AnsiString можно использовать вот такой метод:

char Str1[]={'H','e','l','l','o','\0'};
AnsiString AStr;
 
AStr=AnsiString(Str1);

Преобразование выполняется до первого встреченного нультерминатора. То есть, если массив выглядел, скажем, вот так: {‘H’,’e’,’\0′,’l’,’o’,’\0′}, то после преобразования его в AnsiString, полученная строка будет выглядеть так: «He».

Некоторые полезные методы класса AnsiString

Как узнать количество символов в строке? Length
Как проверить — пустая строка или нет? IsEmpty
Как вставить подстроку внутрь строки? Insert
Как удалить часть строки? Delete
Как привести все символы строки к нижнему регистру? LowerCase
Как привести все символы строки к верхнему регистру? UpperCase
Как узнать, содержится ли подстрока в строке? Pos, AnsiPos
Как получить подстроку из строки? SubString
Как преобразовать строку в целое число? ToInt, ToIntDef
Как преобразовать целое число в строку? IntToHex
Как убрать пробелы в начале и в конце строки? Trim, TrimLeft, TrimRight

С AnsiString можно выполнять операции сложения и сравнения: + , == , != , > , ≥ , < , ≤ . То есть можно, например, написать вот такой код:

AnsiString AStr1="Hello ", AStr2="world!";
AStr1+=AStr2; // теперь AStr1="Hello world!"

Операции сравнения работают следующим образом: начиная с самого первого символа обе строки посимвольно сравниваются (сравниваются коды символов) и если очередные сравниваемые символы не совпадают, то строка, у которой символ имеет меньший код считается меньше. На этом операция сравнения заканчивается и остальные символы не сравниваются. Если строки имеют разную длину и одна из них целиком содержится в начале другой строки, то меньше считается та строка, которая короче.

Как узнать количество символов в строке?

int StrLen=AStr.Length();

Как проверить — пустая строка или нет?

bool StrEmp=AStr.IsEmpty();

Как вставить подстроку внутрь строки?

AnsiString AStr; // строка, в которую нужно вставить
AnsiString SStr; // подстрока, которую нужно вставить
int Ind; // позиция символа, перед которым вставляется подстрока
         // если указать индекс меньше 1, строка вставится перед
         // первым символом, если больше Length, то после последнего
AStr.Insert(SStr,Ind);

Как удалить часть строки?

AnsiString AStr; // строка, из которой нужно удалить часть
AnsiString NStr; // новая строка, которая получится в результате
int Ind;         // позиция первого символа для удаления
int Count;       // количество символов, которое нужно удалить
 
NStr=AStr.Delete(Ind,Count);

Как привести все символы строки к нижнему регистру?

AnsiString AStr; // строка, которую нужно изменить
AnsiString NStr; // новая строка, которая получится
 
NStr=AStr.LowerCase(); // исходная строка не меняется

Как привести все символы строки к верхнему регистру?

AnsiString AStr; // строка, которую нужно изменить
AnsiString NStr; // новая строка, которая получится
 
NStr=AStr.UpperCase(); // исходная строка не меняется

Как узнать, содержится ли подстрока в строке?

AnsiString AStr; // строка, которую нужно проверить
AnsiString SStr; // подстрока, которую ищем
 
int SubStrPos1=AStr.AnsiPos(SStr); // возвращает индекс первого символа
                 // первого вхождения подстроки SStr в строку AStr
                 // или 0, если подстрока в строке не содержится
                 // подходит для многобайтных символов
int SubStrPos2=AStr.Pos(SStr); // аналогично предыдущему, но
                 // не подходит для многобайтных символов

Как получить подстроку из строки?

AnsiString AStr; // исходная строка
AnsiString SStr; // подстрока, которую получим
int index; // позиция первого символа подстроки
int count; // количество символов в подстроке
 
SStr=AStr.SubString(index,count);

Как преобразовать строку в целое число?

AnsiString AStr; // строка, которую нужно преобразовать
int DVal;        // значение по умолчанию для ToIntDef
 
int V1=AStr.ToInt(); // если строка не отображает целое число -
                     // генерирует исключение EConvertError
int V2=AStr.ToIntDef(DVal); // если строка не отображает целое число -
                     // возвращает значение по умолчанию
// если в начале строки есть нули (например так: 00152) - не страшно,
// они будут убраны автоматически

Как преобразовать целое число в строку?

AnsiString AStr; // строка
int Value;       // преобразуемое число
int Dig;         // минимальное количество символов в получаемой строке
 
AStr=IntToHex(Value,Dig); // например, если Value=74 (0x4A) и Dig=4, то
                 // в результате преобразования мы получим AStr="004A"

Как убрать пробелы в начале и в конце строки?

AnsiString AStr; // исходная строка
AnsiString NStr; // новая строка
 
NStr=AStr.Trim();      // убирает пробелы в конце и в начале
NStr=AStr.TrimLeft();  // убирает пробелы в начале
NStr=AStr.TrimRight(); // убирает пробелы в конце

Добавить комментарий