На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела FAQ в группе разделов С++.
1. Раздел FAQ предназначен для публикации готовых статей.
2. Здесь нельзя задавать вопросы, для этого существуют соответствующие разделы:
Чистый С++
Visual C++ / MFC / WTL / WinApi
Borland C++ Builder
COM / DCOM / ActiveX / ATL
Сопутствующие вопросы
3. Внимание, все темы и сообщения в разделе премодерируются. Любое сообщение или тема будут видны остальным участникам только после одобрения модератора.
Модераторы: B.V., Qraizer
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Массив строк - трудный выбор
    Часто приходится работать с массивами строк. Тот, кто поизучал С++ сразу же знает ответ:
    "нужно сделать указатель на указатель - что то вроде вот такого - char **mStings;".
    "ладно", скажу я, "ответ правильный". Но не до конца.
    Такой способ можно использовать, когда речь идет о простом хранении такого массива.
    А если захотим поманипулировать?
    Представим ситуацию: нужно добавить несколько строк куда нибудь в середину.
    Потом отсортировать по алфавиту то что получилось. И уж напоследок убить несколько
    записей середины списка...
    ну как, есть идеи на тему, "как бы это такое сделать и при этом закончить желательно
    до отпуска, который начнется в июле?"
    Если сразу рваться в бой, то закончить можно как раз к отпуску. Вечные проблемы с переаллоцированием,
    чуть зазевался и перепутал индекс - и пожалуйста - получите Аксесс Виолейшн и распишитесь...
    А если чуть чуть подумать, то ясно лучше воспользоваться обертками.

    Первый вариант (MFC): использовать CStringArray или CListString. Вариант вполне достойный,
    если вы пишете с использование MFC. Однако ради одних массивов строк зависеть от каких
    то внешних dll-ек.. нелогично. Ради них же линковать MFC статически нелогично вдвойне.
    А еще бывают платформы, до которых MS еще просто не добрался!

    Второй вариант (STL): vector <string> vStrings или list <string> lStrings.
    в STL много приятных фишечек, помогающих работать со строками и массивами. Над переаллоциро-
    ванием парится уже не програмер, а STL, справляется кстати неплохо. наслаждейтесь.
    STL добрался до всех современных платформ, где есть C++. Не встречал я его только в
    DOS-овых версих: Borland C++ (3.1 например), так же нет уверености по поводу ранних
    версий VC. (самая старшая, которую видел я - 4.2, и там он уже был).


    Код, который демонстрирует, как из такого массива
    удалять строки по условию:

    ExpandedWrap disabled
       
      #include <vector>
      #include <string>
      #include <algorithm>
       
      //эта функция определяет условие по которому будет проводится удаление
      bool Conditions(std::string  x)
      {
        return (x == "235315");
      }
       
      .......
       
        std::vector<std::string> sIn;
       
        int i = 0;
        std::vector<std::string>::iterator new_end;
       
        sIn.push_back("235315");
        sIn.push_back("235315");
        sIn.push_back("235315");
        sIn.push_back("asdg5");
        sIn.push_back("235315");
        sIn.push_back("fb346346");
        sIn.push_back("235315");
       
        for(i = 0; i< sIn.size(); i++)
        {
          printf("%s\n", sIn.at(i).c_str());
        }
       
        printf("\n\n");
       
        new_end = std::remove_if(sIn.begin(), sIn.end(), Conditions);
        sIn.erase(new_end, sIn.end());
       
        for(i = 0; i< sIn.size(); i++)
        {
          printf("%s\n", sIn.at(i).c_str());
        }


    Условие Conditions() можно делать любым, по вашему желанию.

    например: таким

    ExpandedWrap disabled
       
      bool Conditions(std::string  x)
      {
        return (x.at(0) == '2');
      }


    удаляет все строки, которые начинаются на символ '2'


    Сортировка

    std::sort(sIn.begin(), sIn.end(), Conditions2);

    по алфавиту:
    ExpandedWrap disabled
       
      bool Conditions2(std::string  x, std::string  y)
      {
        return (strcmp(x.c_str(), y.c_str()) < 0);
      }


    супротив алфавита:
    ExpandedWrap disabled
       
      bool Conditions2(std::string  x, std::string  y)
      {
        return (strcmp(x.c_str(), y.c_str()) > 0);
      }


    по длине строки:
    ExpandedWrap disabled
       
      bool Conditions2(std::string  x, std::string  y)
      {
        return (x.size() < y.size());
      }




    to be continued...

    (мужики, предлагайте что ещё добавить можно, а то у меня дистрофия фантазии развивается)
    Сообщение отредактировано: AQL -
      Иногда нужно использовать разбор строк. Вот пример часто используемых методов класса string.
      Использовать можно в любом компиляторе.

      ExpandedWrap disabled
         
        string str("arg1 arg2 arg3");
        int i;
         
        while ( (i = str.find(" ")) != -1 ) {
           string temp = str.substr (0, i);
           str.erase (0, i+1);
         
           temp += strimg (" tail");
         
           printf ( "%s\n", str.c_str() );
        }
        эта такая реклама stl? не спорю, вещь полезная, но бесполезная (вернее недоступная) когда имеешь дело с простым С. сейчас пишу одну либину для палма, там по определенным причинам нельзя подключить stl и другие либы для работы со строками и массивами. парилки хватае (мягко говоря). пока что придумал тока такой вариант (благо, что массивы строк заранее известны).

        ExpandedWrap disabled
           
          char* arrStrings[] = {
                                 "aaa",
                                 "bbb",
                                 "ccc"
                                };

        в таком случае еще более менее удобно работать со строками (индексировать, манипулировать и так далее). а вообче то сложно конечно.
        Сообщение отредактировано: bugger -
          Реклама, или не реклама, но 90 процентов нужд перекрывает.
          И 99 процентов вопросов в форуме на эту тему.
            Какая-то куцая статейка :D Может действительно расскажете несколько примеров использования CStringArray и string. Даже не несколько примеров, а вообще рассказать побольше о них. Но начало положено отличное :) молодец AQL :)
              А у меня вопрос .а как насчёт фришного QT версии так скажем 2.3.0
              Динамическая библиотека весит 2700 кило
              Либа - 3200

              Ну плюс ещё мок на 200 килобайт :-)))) ну уж и плюс qtmain.lib & qtutil.lib на 50 кб :-)))

              Вот мне например очень этот вариант понравился, когда я выбирал на чём писать курсовую...

              Я тут сначала попросту забыл написать о главном: это класс QStringList построенная на шаблоне QValueList + адаптированная именно длля работы со строками добавлением соответствующих методов:
              sort
              grep
              split
              join
              Сообщение отредактировано: Allender -
                Цитата Leprecon @ 17.03.04, 21:30
                Какая-то куцая статейка :D Может действительно расскажете несколько примеров использования CStringArray и string. Даже не несколько примеров, а вообще рассказать побольше о них. Но начало положено отличное :) молодец AQL :)

                Хоккей, доделаю. (статейка на редкость куцая)
                  Обещаное продолжение

                  Код, который демонстрирует, как из такого массива
                  удалять строки по условию:

                  ExpandedWrap disabled
                     
                    #include <vector>
                    #include <string>
                    #include <algorithm>
                     
                    //эта функция определяет условие по которому будет проводится удаление
                    bool Conditions(std::string  x)
                    {
                      return (x == "235315");
                    }
                     
                    .......
                     
                      std::vector<std::string> sIn;
                     
                      int i = 0;
                      std::vector<std::string>::iterator new_end;
                     
                      sIn.push_back("235315");
                      sIn.push_back("235315");
                      sIn.push_back("235315");
                      sIn.push_back("asdg5");
                      sIn.push_back("235315");
                      sIn.push_back("fb346346");
                      sIn.push_back("235315");
                     
                      for(i = 0; i< sIn.size(); i++)
                      {
                        printf("%s\n", sIn.at(i).c_str());
                      }
                     
                      printf("\n\n");
                     
                      new_end = std::remove_if(sIn.begin(), sIn.end(), Conditions);
                      sIn.erase(new_end, sIn.end());
                     
                      for(i = 0; i< sIn.size(); i++)
                      {
                        printf("%s\n", sIn.at(i).c_str());
                      }


                  Условие Conditions() можно делать любым, по вашему желанию.

                  например: таким

                  ExpandedWrap disabled
                     
                    bool Conditions(std::string  x)
                    {
                      return (x.at(0) == '2');
                    }


                  удаляет все строки, которые начинаются на символ '2'


                  Сортировка

                  std::sort(sIn.begin(), sIn.end(), Conditions2);

                  по алфавиту:
                  ExpandedWrap disabled
                     
                    bool Conditions2(std::string  x, std::string  y)
                    {
                      return (strcmp(x.c_str(), y.c_str()) < 0);
                    }


                  супротив алфавита:
                  ExpandedWrap disabled
                     
                    bool Conditions2(std::string  x, std::string  y)
                    {
                      return (strcmp(x.c_str(), y.c_str()) > 0);
                    }


                  по длине строки:
                  ExpandedWrap disabled
                     
                    bool Conditions2(std::string  x, std::string  y)
                    {
                      return (x.size() < y.size());
                    }




                  to be continued...

                  (мужики, предлагайте что ещё добавить можно, а то у меня дистрофия фантазии развивается)
                  Сообщение отредактировано: AQL -
                    Загрузка строк из потока
                    ExpandedWrap disabled
                       
                         std::ifstream is("some_file.txt"); // вообще is может быть любым потоком, например cin
                         std::vector<std::string> strings;
                         std::copy(std::istream_iterator<std::string>(is), std::istream_iterator<std::string>(),
                           std::back_inserter(strings));


                    Сохранение строк в поток
                    ExpandedWrap disabled
                       
                         std::vector<std::string> strings;
                         // как-то заполняем strings
                         std::ofstream os("some_file.txt"); // вообще os может быть любым потоком, например cout
                         std::copy(strings.begin(), strings.end(), std::ostream_iterator<std::string>(os, "\n"));
                      Цитата Allender @ 18.03.04, 13:32
                      А у меня вопрос .а как насчёт фришного QT версии так скажем 2.3.0
                      Динамическая библиотека весит 2700 кило
                      Либа - 3200

                      Ну плюс ещё мок на 200 килобайт :-)))) ну уж и плюс qtmain.lib & qtutil.lib на 50 кб :-)))

                      Вот мне например очень этот вариант понравился, когда я выбирал на чём писать курсовую...

                      Я тут сначала попросту забыл написать о главном: это класс QStringList построенная на шаблоне QValueList + адаптированная именно длля работы со строками добавлением соответствующих методов:
                      sort
                      grep
                      split
                      join

                      Что можно делать с QStringList:
                      ExpandedWrap disabled
                         
                        QStringList::sort()

                      -сортировка в порядке возрастания, если нужна другая другая сортировка, то можно написать в ручную, дабы алгоритмы всем известны используя функции для работы со списком, о которых будет сказано позжее.
                      ExpandedWrap disabled
                         
                        QString QStringList::join ( const QString & sep ) const

                      -Объединяет весь список в одну строку
                      ExpandedWrap disabled
                         
                        QStringList QStringList::split( const QRegExp & sep или const QString & sep или const QChar & sep, const QString & str, bool allowEmptyEntries = FALSE ) [static]

                      -позволяет с помощью какого либо сепаратора (регулярное выражение, строка или символ)разделить одну единую строку на список (очень удобно для парсинга)
                      ExpandedWrap disabled
                         
                        QStringList QStringList::grep ( const QString & str, bool cs = TRUE ) const
                        //или
                        QStringList QStringList::grep ( const QRegExp & expr ) const

                      -позволяет получить новый список строк, каждая строка которого будет содержать строку str либо удовлетворять регулярному выражению expr

                      Теперь, что позволяет деалть QStringList за счёт методов класса QValueList, от которого он отнаследован.
                      Во-первых поддерживается механизм итераторов для более удобной и безопасной навигации
                      ExpandedWrap disabled
                         
                        QValueList<T> & operator= ( const QValueList<T> & l )
                        QValueList<T> & operator= ( const std::list<T> & l )
                        bool operator== ( const std::list<T> & l ) const
                        bool operator== ( const QValueList<T> & l ) const
                        bool operator!= ( const QValueList<T> & l ) const

                      -как видите поддерживается и обычный std::list<T>
                      ExpandedWrap disabled
                         
                        terator begin ()
                        const_iterator begin () const
                        iterator end ()
                        const_iterator end () const
                        iterator insert ( iterator it, const T & x )
                        uint remove ( const T & x )
                        void clear ()
                        iterator erase ( iterator it )
                        iterator erase ( iterator first, iterator last )

                      - элементарная работа с итераторами
                      ExpandedWrap disabled
                         
                        T & operator[] ( size_type i )
                        const T & operator[] ( size_type i ) const
                        iterator at ( size_type i )
                        const_iterator at ( size_type i ) const
                        iterator find ( const T & x )
                        const_iterator find ( const T & x ) const
                        iterator find ( iterator it, const T & x )
                        const_iterator find ( const_iterator it, const T & x ) const
                        int findIndex ( const T & x ) const
                        size_type contains ( const T & x ) const
                        size_type count () const
                        QValueList<T> & operator+= ( const T & x )

                      - а также ещё немного методов. которые облегчают интерфейс пользования этим самым QStringList
                        А как std::string конвертировать в int, double, float и обратно?

                        С Уважением,

                        dangee
                          Цитата dangee @ 31.03.04, 08:50
                          А как std::string конвертировать в int, double, float и обратно?

                          С Уважением,

                          dangee

                          Извини конечно за навязчивость, но вот есть и такая алтернатива :-))))
                          Правда это всё для класса QString...

                          ExpandedWrap disabled
                             
                            short toShort ( bool * ok = 0, int base = 10 ) const
                            ushort toUShort ( bool * ok = 0, int base = 10 ) const
                            int toInt ( bool * ok = 0, int base = 10 ) const
                            uint toUInt ( bool * ok = 0, int base = 10 ) const
                            long toLong ( bool * ok = 0, int base = 10 ) const
                            ulong toULong ( bool * ok = 0, int base = 10 ) const
                            float toFloat ( bool * ok = 0 ) const
                            double toDouble ( bool * ok = 0 ) const
                            QString & setNum ( short n, int base = 10 )
                            QString & setNum ( ushort n, int base = 10 )
                            QString & setNum ( int n, int base = 10 )
                            QString & setNum ( uint n, int base = 10 )
                            QString & setNum ( long n, int base = 10 )
                            QString & setNum ( ulong n, int base = 10 )
                            QString & setNum ( float n, char f = 'g', int prec = 6 )
                            QString & setNum ( double n, char f = 'g', int prec = 6 )
                            Спасибо!

                            Но как это сделать в классике ( :) )?

                            ЗЫ. Почему я всегда выбираю трудный путь?
                              Цитата
                              dangee, 31.03.04, 08:50
                              А как std::string конвертировать в int, double, float и обратно?

                              А про это вот здесь написано.
                                AQL, Allender, может как-нить скооперируетесь, чтобы скомпоновать окончательную версию и поместить ее в первое сообщение этого топика?
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0931 ]   [ 16 queries used ]   [ Generated: 25.04.24, 07:10 GMT ]