C++ Builder: как разбить строку на массив

Как это не прискорбно, но в C++ Builder работа со строками находится на зачаточном уровне. Именно поэтому, для разбиения строки на массив придется создавать цикл.

Например, имеется строка содержащая неопределенное количество элементов через пробел. Для разбиения такой строки на массив нам, прежде всего, понадобится узнать длину строки.

Это можно сделать так при помощи функции Length(). Например, так:

int len=was.Length();

где was – непосредственно разбиваемая строка.

Непосредственное разбиение этой строки на массив может быть осуществлено в таком цикле:

String od,dv;
for (int i=1;i<=len;i++)
 {
dv=was.SubString(i,1);
if(dv != " ") od+=was.SubString(i,1);
else          {W[wh]=StrToFloat(od); od=""; wh++; }
 }

Пояснить работу цикла можно так: строка разбивается посимвольно при помощи функции SubString(). Каждый символ, полученный таким способом, сравнивается с пробелом. Если он не равен пробелу, то происходит запись этого символа в строку (простым добавлением), если же равен, то записанные до пробела элементы вносятся в массив W[wh] (при этом используется явное преобразование StrToFloat()).

В целом, ничего сложного, как видите, в разбиении строки на массив нет.

UPD
Еще один вариант разбиения строки (подсказан MasterGray).
Его основа — свойство Delimiter (класса TStringList).

TStringList * MyList = new TStringList(); //объявляем
MyList->Delimiter = L':';                 //определяем разделитель (по умолчанию - пробел)
MyList->DelimitedText = "123:12:1234:123";//разбиваем строку
MyList->operator[](int Index);            //получаем результат (в скобках - индекс массива, отсчет с 0)

И еще (скопирована часть комментирия MasterGray):
Отмечу еще пару моментов:
1. Создание класса через new должно обязательно заканчиваться вызовом delete. Это азы, но увы в пылу кодинга об этом часто забывают.
2. TStringList – не просто массив, а список, поэтому его можно сортировать и искать по значению встроенными методами
3. И самое главное свойства Name/Value. Пример:

TStringList * MyList = new TStringList(); 
MyList->NameValueSeparator;//по умолчанию «=»
MyList->Add(«Sasha=Petrov»);//добавили строку
MyList->Names[0];//==»Sasha»
//в этом варианте существование имени в массиве
//надо проверять самому:
MyList->Values["Sasha"];//==Petrov
MyList->ValueFromIndex[0];//==Petrov
delete MyList;

18 comments on “C++ Builder: как разбить строку на массив

  1. Неплохо было бы для начала указать версию Билдера которым Вы пользуетесь. Реализация строк в C++ Builder`e — имхо лучшая.
    String — это не класс, а макрос, автоматически подставляющий
    AnsiString или UnicodeString. В обоих этих классах строка уже
    АВТОМАТИЧЕСКИ ЯВЛЯЕТСЯ МАССИВОМ СИМВОЛОМ))), и к ее элементам можно обращаться через индекс:
    AnsiString S = «345»;
    S[1]//будет равно (char)3
    Для AnsiString элементом является однобайтный char,
    для UnicodeString — двухбайтный wchar_t.
    Также для удаления всех пробелов в начале или в конце строки существуют методы Trim, TrimLeft и trimRight

    1. Пользуюсь 6 версией.

      Реализация строк в C++ Builder`e – имхо лучшая.

      Эээ… ну… смотря с чем сравнивать. Для примера, в java имеется функция split разбивающая строку на подстроки, т.е. разбить можно легко и просто, например так:

      1
      2
      
      String s="123:12:1234:123";
      String [] sub = s.split(":");

      В php тоже имеется соответствующая функция:

      1
      2
      
      $str="123:12:1234:123";
      $arr = explode(":", $str);

      А в C++ Builder таковой нет (или я ошибаюсь?) и для выполнения простой операции приходится писать цикл.

      String – это не класс, а макрос, автоматически подставляющий
      AnsiString или UnicodeString. В обоих этих классах строка уже
      АВТОМАТИЧЕСКИ ЯВЛЯЕТСЯ МАССИВОМ СИМВОЛОМ))), и к ее элементам можно обращаться через индекс:
      AnsiString S = «345»;
      S[1]//будет равно (char)3

      Да, я поняла, что вы хотите сказать, но задача стояла другая. На тот момент была надобность разбить строку не посимвольно, а почисельно (если можно так выразиться).
      Это раз. И два:

      String – это не класс, а макрос

      Это игра в слова? Я, возможно, заблуждаюсь (поправите?), но в чем разница? В названии?
      Класс — это ведь не тип данных, у класса имеются поля, методы, свойства, в конце концов. Макрос понятие более узкое (свойств, пожалуй, у него нет — остальное в наличии)…
      Т.е. высказывание:
      Петров Саша — это не млекопитающее, это человек.
      аналогично вашему (по-моему).
      В общем, String — это строковый класс.

      Также для удаления всех пробелов в начале или в конце строки существуют методы Trim, TrimLeft и trimRight

      Да, спасибо, эти функции я нашла, но опять же — задача была другая и для ее решения они не подходили.

      1. 1. Эээ… ну… смотря с чем сравнивать.
        Пардон, моя ошибка — я сравнивал с другими средами разработки под С++: M$ Visual Studio и QT — там только определенный стандартом
        std::string (хотя QT знаю не настолько глубоко, может там свое что-то и есть)
        2. Строка вида «123:12:1234:123» разбивается так:
        TStringList * MyList = new TStringList();
        MyList->Delimiter = L’:’;
        MyList->

      2. MyList->DelimitedText = «123:12:1234:123»;
        MyList->operator[](int Index);
        обращение через метод operator[](int Index) здесь вынужденное, из-за кривой поддержки Борландом шаблонов и функций-операторов

        1. Спасибо большое!
          Надеюсь, вы не против будете, если я добавлю вариант в постик (может поможет кому )))… (?)

          1. Конечно не против))) Всегда пожалуйста
            Отмечу еще пару моментов:
            1. Создание класса через new должно обязательно
            заканчиваться вызовом delete. Это азы, но увы в пылу кодинга об этом часто забывают.
            2. TStringList — не просто массив, а список, поэтому его можно сортировать и искать по значению встроенными методами
            3. И самое главное свойства NameValue. Пример:
            TStringList * MyList = new TStringList(); MyList->NameValueSeparator;//по умолчанию «=»
            MyList->Add(«Sasha=Petrov»);//добавили строку
            MyList->Names[0];//==»Sasha»
            //в этом варианте существование имени в массиве
            //надо проверять самому:
            MyList->Values[«Sasha»];//==Petrov
            MyList->ValueFromIndex[0];//==Petrov
            delete MyList;
            Собственно, говоря о мощи строк именно в
            С++ Builder`e я в первую очередь имел ввиду
            TStringList

  2. P.S. Нумерация массивов для строк в Билдере начинается с 1, в отличие от всех остальных массивов.
    P.P.S. Удачи в начинаниях, очень приятно видеть в наших рядах
    представительниц прекрасного пола)))

    1. P.S. Нумерация массивов для строк в Билдере начинается с 1, в отличие от всех остальных массивов.

      Я обратного и не писала.

      P.P.S. Удачи в начинаниях, очень приятно видеть в наших рядах
      представительниц прекрасного пола)))

      Спасибо =)

  3. Поправлю.

    Вышеуказанный метод (с Delimiter) не корректно работает с пробелом. Он его всегда учитывает, даже если этого не нужно.
    Сам давиче мучился такой проблемой, нужно было корректно отделять имена файлов и помещать в список.
    Вот, что нашел:

    1
    2
    3
    4
    5
    
    AnsiSrtring GetPath = "";
     
    TSysCharSet Tws,Tcs;
    Tcs<<';'<<':'<Text = GetPath;
    ExtractStrings(Tcs,Tws,GetPath.c_str(),ListBox1-&gt;Items);

    ИМХО, очень элегантный способ.

  4. Чего-то с тэгом кода у Вас. Разделители пляшут…
    Вот правильный исходный текст:

    AnsiSrtring GetPath = «»;
    TSysCharSet Tws,Tcs;
    Tcs<<';'<<':'<Text = GetPath;
    ExtractStrings(Tcs,Tws,GetPath.c_str(),ListBox1->Items);

    1. есть такое. ВП ведь считает такого рода символы потенциально опасными — вот и заменяет )

  5. В php тоже имеется соответствующая функция:
    $str=»123:12:1234:123″;
    $arr = explode(«:», $str);

    У меня почему не разбивает. Говорит
    explode() expects parameter 2 to be string, array given

    1. Хм… в файле 1.php такой код

      1
      2
      3
      4
      5
      
      <?php
      $str="123:12:1234:123";
      $arr = explode(":", $str);
      print_r($arr); 
      ?>

      Результат тут http://femils-pro.ru/1.php
      Как видно — все работает.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *