Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.15.219.217] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Часто приходится работать с массивами строк. Тот, кто поизучал С++ сразу же знает ответ:
"нужно сделать указатель на указатель - что то вроде вот такого - 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, и там он уже был). Код, который демонстрирует, как из такого массива удалять строки по условию: #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() можно делать любым, по вашему желанию. например: таким bool Conditions(std::string x) { return (x.at(0) == '2'); } удаляет все строки, которые начинаются на символ '2' Сортировка std::sort(sIn.begin(), sIn.end(), Conditions2); по алфавиту: bool Conditions2(std::string x, std::string y) { return (strcmp(x.c_str(), y.c_str()) < 0); } супротив алфавита: bool Conditions2(std::string x, std::string y) { return (strcmp(x.c_str(), y.c_str()) > 0); } по длине строки: bool Conditions2(std::string x, std::string y) { return (x.size() < y.size()); } to be continued... (мужики, предлагайте что ещё добавить можно, а то у меня дистрофия фантазии развивается) |
Сообщ.
#2
,
|
|
|
Иногда нужно использовать разбор строк. Вот пример часто используемых методов класса string.
Использовать можно в любом компиляторе. 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() ); } |
Сообщ.
#3
,
|
|
|
эта такая реклама stl? не спорю, вещь полезная, но бесполезная (вернее недоступная) когда имеешь дело с простым С. сейчас пишу одну либину для палма, там по определенным причинам нельзя подключить stl и другие либы для работы со строками и массивами. парилки хватае (мягко говоря). пока что придумал тока такой вариант (благо, что массивы строк заранее известны).
char* arrStrings[] = { "aaa", "bbb", "ccc" }; в таком случае еще более менее удобно работать со строками (индексировать, манипулировать и так далее). а вообче то сложно конечно. |
Сообщ.
#4
,
|
|
|
Реклама, или не реклама, но 90 процентов нужд перекрывает.
И 99 процентов вопросов в форуме на эту тему. |
Сообщ.
#5
,
|
|
|
Какая-то куцая статейка Может действительно расскажете несколько примеров использования CStringArray и string. Даже не несколько примеров, а вообще рассказать побольше о них. Но начало положено отличное молодец AQL
|
Сообщ.
#6
,
|
|
|
А у меня вопрос .а как насчёт фришного QT версии так скажем 2.3.0
Динамическая библиотека весит 2700 кило Либа - 3200 Ну плюс ещё мок на 200 килобайт :-)))) ну уж и плюс qtmain.lib & qtutil.lib на 50 кб :-))) Вот мне например очень этот вариант понравился, когда я выбирал на чём писать курсовую... Я тут сначала попросту забыл написать о главном: это класс QStringList построенная на шаблоне QValueList + адаптированная именно длля работы со строками добавлением соответствующих методов: sort grep split join |
Сообщ.
#7
,
|
|
|
Цитата Leprecon @ 17.03.04, 21:30 Какая-то куцая статейка Может действительно расскажете несколько примеров использования CStringArray и string. Даже не несколько примеров, а вообще рассказать побольше о них. Но начало положено отличное молодец AQL Хоккей, доделаю. (статейка на редкость куцая) |
Сообщ.
#8
,
|
|
|
Обещаное продолжение
Код, который демонстрирует, как из такого массива удалять строки по условию: #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() можно делать любым, по вашему желанию. например: таким bool Conditions(std::string x) { return (x.at(0) == '2'); } удаляет все строки, которые начинаются на символ '2' Сортировка std::sort(sIn.begin(), sIn.end(), Conditions2); по алфавиту: bool Conditions2(std::string x, std::string y) { return (strcmp(x.c_str(), y.c_str()) < 0); } супротив алфавита: bool Conditions2(std::string x, std::string y) { return (strcmp(x.c_str(), y.c_str()) > 0); } по длине строки: bool Conditions2(std::string x, std::string y) { return (x.size() < y.size()); } to be continued... (мужики, предлагайте что ещё добавить можно, а то у меня дистрофия фантазии развивается) |
Сообщ.
#9
,
|
|
|
Загрузка строк из потока
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)); Сохранение строк в поток 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")); |
Сообщ.
#10
,
|
|
|
Цитата 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: QStringList::sort() -сортировка в порядке возрастания, если нужна другая другая сортировка, то можно написать в ручную, дабы алгоритмы всем известны используя функции для работы со списком, о которых будет сказано позжее. QString QStringList::join ( const QString & sep ) const -Объединяет весь список в одну строку QStringList QStringList::split( const QRegExp & sep или const QString & sep или const QChar & sep, const QString & str, bool allowEmptyEntries = FALSE ) [static] -позволяет с помощью какого либо сепаратора (регулярное выражение, строка или символ)разделить одну единую строку на список (очень удобно для парсинга) QStringList QStringList::grep ( const QString & str, bool cs = TRUE ) const //или QStringList QStringList::grep ( const QRegExp & expr ) const -позволяет получить новый список строк, каждая строка которого будет содержать строку str либо удовлетворять регулярному выражению expr Теперь, что позволяет деалть QStringList за счёт методов класса QValueList, от которого он отнаследован. Во-первых поддерживается механизм итераторов для более удобной и безопасной навигации 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> 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 ) - элементарная работа с итераторами 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 |
Сообщ.
#11
,
|
|
|
А как std::string конвертировать в int, double, float и обратно?
С Уважением, dangee |
Сообщ.
#12
,
|
|
|
Цитата dangee @ 31.03.04, 08:50 А как std::string конвертировать в int, double, float и обратно? С Уважением, dangee Извини конечно за навязчивость, но вот есть и такая алтернатива :-)))) Правда это всё для класса QString... 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 ) |
Сообщ.
#13
,
|
|
|
Спасибо!
Но как это сделать в классике ( )? ЗЫ. Почему я всегда выбираю трудный путь? |
Сообщ.
#14
,
|
|
|
Цитата dangee, 31.03.04, 08:50 А как std::string конвертировать в int, double, float и обратно? А про это вот здесь написано. |
Сообщ.
#15
,
|
|
|
AQL, Allender, может как-нить скооперируетесь, чтобы скомпоновать окончательную версию и поместить ее в первое сообщение этого топика?
|