Что-то я не пойму до конца всю прелесть типа string.
Как мне получить доступ к самомоу буферу? Ведь c_str() возвращает константу :\
Например, как мне использовать тип string для получения текста окна?
string s("");
GetWindowText(...???...);
...И еще один маленький вопросик, как можно отформатировать эту строку?.. Конечно, если получить доступ к буферу, то вопрос снимается — sprintf, а есть ли встроенный метод, что-то я его не нашел. Спасибо!
Здравствуйте, Аноним, Вы писали:
А> Что-то я не пойму до конца всю прелесть типа string. А> Как мне получить доступ к самомоу буферу? Ведь c_str() возвращает константу :\
Такой возможности нет.
А> Например, как мне использовать тип string для получения текста окна?
А> string s(""); А> GetWindowText(...???...);
Используй std::vector<> или MFC/ATL CString.
А> ...И еще один маленький вопросик, как можно отформатировать эту строку?.. Конечно, если получить доступ к буферу, то вопрос снимается — sprintf, а есть ли встроенный метод, что-то я его не нашел. Спасибо!
Используй boost::format или std::stringstream. На крайняк MFC/ATL CString и sprintf в их буфер.
Меня эта "недоделанность" всегда раздражала:
класс string есть
другие классы этой библиотеки его не использует практически нигде, обычно все сводится к char* (см. exception, stringstream)
возможности использовать с уже существующем кодом минимальны (нет поступа к буфферу)
функций форматирования нету (разве что опять через char* так или иначе)
Здравствуйте, MaximE, Вы писали:
ME>Здравствуйте, Аноним, Вы писали:
А>> Что-то я не пойму до конца всю прелесть типа string. А>> Как мне получить доступ к самомоу буферу? Ведь c_str() возвращает константу :\
ME>Такой возможности нет.
Вот в этом — то и прелесть — более безопасный код
Опыт — это такая вещь, которая появляется сразу после того, как была нужна...
> Что-то я не пойму до конца всю прелесть типа string. > Как мне получить доступ к самомоу буферу? Ведь c_str() возвращает > константу :\ Например, как мне использовать тип string для получения > текста окна? > > string s(""); > GetWindowText(...???...);
Тов. Майерс в "Effective STL" пишет, что для этого нужно использовать промежуточный буфер, примерно так:
> ...И еще один маленький вопросик, как можно отформатировать эту > строку?.. Конечно, если получить доступ к буферу, то вопрос снимается - > sprintf, а есть ли встроенный метод, что-то я его не нашел. Спасибо!
Здравствуйте, MaximE, Вы писали:
А>> string s(""); А>> GetWindowText(...???...);
ME>Используй std::vector<> или MFC/ATL CString.
А>> ...И еще один маленький вопросик, как можно отформатировать эту строку?.. Конечно, если получить доступ к буферу, то вопрос снимается — sprintf, а есть ли встроенный метод, что-то я его не нашел. Спасибо!
ME>Используй boost::format или std::stringstream. На крайняк MFC/ATL CString и sprintf в их буфер.
То есть ты хочешь подтвердить мое мнение о том, что ситуация плоха? Дык, а в чем тогда секрет? Почему нельзя было сделать по-человечески (только не говори, что это вопрос к тем, кто делал ).
А в чем тогда вообще смысл этого string, если для вызова ЛЮБОЙ функции нужно вводить дополнительные типы?????????? Бред!?
Например, сейчас мне нужно вызвать CharLower для string... Это что ж мне нужно объявлять char * перегонять туда стринг и опять обратно????? :\
Удалено избыточное цитирование. -- ПК.
Re[2]: string
От:
Аноним
Дата:
11.07.03 09:35
Оценка:
Здравствуйте, PM, Вы писали:
>> ...И еще один маленький вопросик, как можно отформатировать эту >> строку?.. Конечно, если получить доступ к буферу, то вопрос снимается - >> sprintf, а есть ли встроенный метод, что-то я его не нашел. Спасибо!
PM>Аналогично, воспользоваться промежуточным буфером std::vector<char>
Это замечательно, но... зачем такой огород?... эх.. понял... не задавать глупых вопросов...
Ладно, но неужели нет хорошей и достаточно совметимой со всем библиотеки, которая позволила бы быстро работать со стоками и имела бы МИНИМАЛЬНЫЙ набор полезных функций??? МИНИМАЛЬНЫЙ — имеется в виду: поиск, форматирование, изменение регистра, корректное и простое удаление и т.д. ?
Гм... А будет ли сие работать корректно, если строка формируемая GetWindowText, паче чаяния, превысит 1023 символа? Если речь идет не о кепшине, а о содержимом контрола, ситуация становится вполне вероятной...
Здравствуйте, <Аноним>, Вы писали:
А> Это замечательно, но... зачем такой огород?... эх.. понял... не задавать глупых вопросов... А> Ладно, но неужели нет хорошей и достаточно совметимой со всем библиотеки, которая позволила бы быстро работать со стоками и имела бы МИНИМАЛЬНЫЙ набор полезных функций??? МИНИМАЛЬНЫЙ — имеется в виду: поиск, форматирование, изменение регистра, корректное и простое удаление и т.д. ?
Я понял!!!
string — это такой академический пример, что разработчики библиотек договорились не реализовывать этот класс нормально — пусть студенты мучаются!
Здравствуйте, Vamp, Вы писали:
V>Гм... А будет ли сие работать корректно, если строка формируемая GetWindowText, паче чаяния, превысит 1023 символа? Если речь идет не о кепшине, а о содержимом контрола, ситуация становится вполне вероятной...
дык. я так понимаю, PM написал примерный код, а получить длину текста можно с помощью GetWindowTextLength().
??>>> Что-то я не пойму до конца всю прелесть типа string.
??>>> string s("");
??>>> GetWindowText(...???...); > PM>> Тов. Майерс в "Effective STL" пишет, что для этого нужно использовать PM>> промежуточный буфер, примерно так:
> Это замечательно, но... зачем такой огород?... эх.. понял... не > задавать глупых вопросов...
Это делается для поддержки старых API, работающих с массивами и строками C.
Настоящие С++ стараются всегда использовать string и vector
> Ладно, но неужели нет хорошей и достаточно совметимой со всем библиотеки, > которая позволила бы быстро работать со стоками и имела бы МИНИМАЛЬНЫЙ > набор полезных функций??? МИНИМАЛЬНЫЙ — имеется в виду: поиск, > форматирование, изменение регистра, корректное и простое удаление и т.д. > ?
На всех не угодишь — напиши свою реализацию Но далеко не факт, что у тебя получится универсальнее/эффективнее и без багов
V> V> Гм... А будет ли сие работать корректно, если строка формируемая V> GetWindowText, паче чаяния, превысит 1023 символа? Если речь идет не о V> кепшине, а о содержимом контрола, ситуация становится вполне V> вероятной...
Строка отрежется. Не принимай близко к сердцу -это ж только пример
А специально для GetWindowText есть GetWindowTextLength
Здравствуйте, Аноним, Вы писали:
А> То есть ты хочешь подтвердить мое мнение о том, что ситуация плоха? Дык, а в чем тогда секрет? Почему нельзя было сделать по-человечески (только не говори, что это вопрос к тем, кто делал ). А> А в чем тогда вообще смысл этого string, если для вызова ЛЮБОЙ функции нужно вводить дополнительные типы?????????? Бред!? А> Например, сейчас мне нужно вызвать CharLower для string... Это что ж мне нужно объявлять char * перегонять туда стринг и опять обратно????? :\
Дело в том, что все эти функции — это C API. Классы stl не предоставляют средств для автоматизации работы с унаследованными API. Для этой цели предназначены такие библиотеки, как MFC и ATL.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, PM, Вы писали:
>>> Что-то я не пойму до конца всю прелесть типа string. >>> Как мне получить доступ к самомоу буферу? Ведь c_str() возвращает >>> константу :\ Например, как мне использовать тип string для получения >>> текста окна? >>>
Естественно! А как иначе? std::string содержит в себе механизмы работы с сырой памятью, механизмы кеширования и др. В этой ситуации доступ к буферу есть дело некорректное. Грабли, т.е. А c_str возвращает константную ссылку. Типа никто не запрещает читать из этого буфера
PM>>Аналогично, воспользоваться промежуточным буфером std::vector<char>
А> Это замечательно, но... зачем такой огород?... эх.. понял... не задавать глупых вопросов...
А в чем огород? Да, с одной стороны можно было бы встроить механизм форматирования в std::string (как это сделано в CString), но... С точки зрения универсальносит и расширяемости стандартной библиотеки, ее безопасности это излишне. Для трюкачества есть механизм, предложенный выше. Для работы со строками есть std::string. Кстати, где то в форуме пробегал класс для форматирования оформленный в стиле std
А> Ладно, но неужели нет хорошей и достаточно совметимой со всем библиотеки, которая позволила бы быстро работать со стоками и имела бы МИНИМАЛЬНЫЙ набор полезных функций??? МИНИМАЛЬНЫЙ — имеется в виду: поиск, форматирование, изменение регистра, корректное и простое удаление и т.д. ?
Что значит совместимыми со всеми библиотеками? типа, std "должны быть совместима с набором функций для поиска фирмы Пупкин и сыновья"? Что касается основных функций для работы со строками, то они представлены в изобилии. см., например, главу 20 "Язык программирования С++"
- Простите, профессор, не пса, а когда он уже был человеком.
— То-есть он говорил? Это еще не значит быть человеком. (с) Булгаков
Re[4]: string
От:
Аноним
Дата:
11.07.03 11:18
Оценка:
Здравствуйте, PM, Вы писали:
PM>На всех не угодишь — напиши свою реализацию Но далеко не факт, что у тебя получится универсальнее/эффективнее и без багов
Да, я помню как кто-то тут уже поднимал вопрос о том, чтобы написать нормальный стринг! Так ведь значит не только я мучаюсь!
Не понимаю все равно... MFC ATL WTL ...это все хорошо, но почему бы не мделать встроенные в язык средства, чтобы люди не городили изо дня в день свои кривые (или не кривые) функции поиска, форматирования и т.д...???
Удалено избыточное цитирование. -- ПК.
Re[4]: string
От:
Аноним
Дата:
11.07.03 11:21
Оценка:
Здравствуйте, small_cat, Вы писали:
А>> Ладно, но неужели нет хорошей и достаточно совметимой со всем библиотеки, которая позволила бы быстро работать со стоками и имела бы МИНИМАЛЬНЫЙ набор полезных функций??? МИНИМАЛЬНЫЙ — имеется в виду: поиск, форматирование, изменение регистра, корректное и простое удаление и т.д. ? _>Что значит совместимыми со всеми библиотеками? типа, std "должны быть совместима с набором функций для поиска фирмы Пупкин и сыновья"? Что касается основных функций для работы со строками, то они представлены в изобилии. см., например, главу 20 "Язык программирования С++"
Плохо выразился. Я имел в виду что-то сделанное на основе char * так, чтобы это было легко применять и в MFC и в ATL и в WTL.
Просто мне не совсем понятно, зачем было писать string, если он, в принципе, недоделан до того, чтобы его можно было легко использовать. Иногда он усложняет жизнь, а не упрощает! ...
Здравствуйте, Аноним, Вы писали:
А> Помогите, пожалуйста, начинающему разобраться
А> Что-то я не пойму до конца всю прелесть типа string. А> Как мне получить доступ к самомоу буферу? Ведь c_str() возвращает константу :\ А> Например, как мне использовать тип string для получения текста окна?
Когда я сам был начинающим (месяца три назад ), столкнувшись точно с такой проблемой, написал свой строковый класс (это был первый класс на С++). Глючил он безбожно, но учитывая наличие всех исходников, где-то в течении года баги исправлялись (я набирался опыта) и даже месяца два у меня небыло к нему никаких претензий... но, на днях нашелся очередной баг
В моем случае прога строилась на WinAPI, и поэтому советы типа:
"Это все устарело..."
"Используйте mfc, vcl..."
не рассматривались.
Вывод: со стандартными классами придется все делать через ж..., НО можно быть практически уверенным, что они НЕ будут глючить. Со своими все наоборот
Правда, может я один такой
PM>> На всех не угодишь — напиши свою реализацию Но далеко не факт, что PM>> у тебя получится универсальнее/эффективнее и без багов > > Да, я помню как кто-то тут уже поднимал вопрос о том, чтобы написать > нормальный стринг! Так ведь значит не только я мучаюсь! Не понимаю все > равно... MFC ATL WTL ...это все хорошо, но почему бы не мделать > встроенные в язык средства, чтобы люди не городили изо дня в день свои > кривые (или не кривые) функции поиска, форматирования и т.д...???
Каждый "реальный" программист должен написать свой класс строки (c) не помню
hi.
A2>Когда я сам был начинающим (месяца три назад ), столкнувшись точно с такой проблемой, написал свой строковый класс (это был первый класс на С++). Глючил он безбожно, но учитывая наличие всех исходников, где-то в течении года баги исправлялись (я набирался опыта) и даже месяца два у меня небыло к нему никаких претензий... но, на днях нашелся очередной баг
У тебя со временем что-то не сходится.. То три месяца назад, то через год...
A2>Вывод: со стандартными классами придется все делать через ж..., НО можно быть практически уверенным, что они НЕ будут глючить. Со своими все наоборот A2>Правда, может я один такой
Вывод: со стандартной библиотекой если нормально всё выучить, можно работать вполне нормально, а недоучившись, оно, конечно, через это самое место. Недоучившись, потом и задаются дурацкие вопросы -- а нахрен надо было такие строки писать??
А оно и не заточено вовсе под работу с GetWindowText() или ещё подобным чем-то. Оно вообще-то, и не знает о существовании WindowsAPI.
hi.
А> То есть ты хочешь подтвердить мое мнение о том, что ситуация плоха? Дык, а в чем тогда секрет? Почему нельзя было сделать по-человечески (только не говори, что это вопрос к тем, кто делал ).
Кто тебе сказал глупость, что оно не по-человечески?
А> А в чем тогда вообще смысл этого string,
В том, что бы избавить программиста по-возможности от работы с типом char*.
А> если для вызова ЛЮБОЙ функции нужно вводить дополнительные типы?????????? Бред!?
Бред то, что ты написал здесь, извини за резкость. Кто тебе вообще сказал, что мир ограничен функциями WinAPI? А твоё утверждение -- бред, потому как для вызова _ЛЮБОЙ_ функции не надо городить дополнительные типы. Твоё утверждение ложно, моё -- нет.
hi.
D>Меня эта "недоделанность" всегда раздражала: D> класс string есть D> другие классы этой библиотеки его не использует практически нигде, обычно все сводится к char* (см. exception, stringstream) D> возможности использовать с уже существующем кодом минимальны (нет поступа к буфферу) D> функций форматирования нету (разве что опять через char* так или иначе)
Совершенный стринг написать невозможно, слишком разные вкусы и потребности у людей. Стандартный стринг не есть недоделанный класс -- он обеспечивает базовый набор операций со строкой, логично вписывается в стандартную библиотеку.
При разработке стринга во главу угла ставили то, чтобы была возможность работать практически с любым существующим набором символов. Поэтому оно такое.
D>Я понял!!! D>string — это такой академический пример, что разработчики библиотек договорились не реализовывать этот класс нормально — пусть студенты мучаются!
А ты реализуй свой стринг, а мы тебе объясним, почему он плохой. Я, например, написал свой стринг, он быстрее стандартного (по-крайней мере на тех платформах и компиляторах, где я его тестировал), удобен тем что в нём есть форматирование, конвртация числовых типов, автоматическая конвертация к char* (меня это больше устраивает, чем вызов c_str() ) и куча всяких удобств для меня. Но он имеет кучу минусов, самым значимым из которых, привязка к свойствам ASCII набора. Так вот, мой стринг хорош весьма, но только для меня. А в стандартной библиотеки универсальный компромис, который помогает избавиться от работы с char*. И именно с этих позиций, мне кажется, надо на него смотреть, потому что универсальный и хороший стринг написать невозможно.
hi.
А> Плохо выразился. Я имел в виду что-то сделанное на основе char * так, чтобы это было легко применять и в MFC и в ATL и в WTL.
Потому что, что-то сделанное на основе char* совсем не будет работать со строками на основе моей любимой кодировки "ЁПРСТ".
А> Просто мне не совсем понятно, зачем было писать string, если он, в принципе, недоделан до того, чтобы его можно было легко использовать. Иногда он усложняет жизнь, а не упрощает! ...
Он доделан. Просто туда, для всех забывающих назначение самого языка и почему он такой, а не иначе, забыли приписать: "Windows & ASCII are not only one way".
Здравствуйте, deviv, Вы писали:
d> Меня эта "недоделанность" всегда раздражала:
Нет тут никакой недоделанности. Скорее, наоборот, std::string несколько перегрузили функциональностью.
d> класс string есть d> другие классы этой библиотеки его не использует практически нигде, d> обычно все сводится к char* (см. exception, stringstream)
Используют. Не смешивай интерфейс и реализацию. Например, в ряде реализаций того же std::exception
переданная строка хранится как std::string. Но вот принимать или возвращать ее
в виде std::string нет никакой необходимости, достаточно const char*.
d> возможности использовать с уже существующем кодом минимальны (нет поступа к буфферу)
А для чего, если есть итераторы и т.п.?
d> функций форматирования нету (разве что опять через char* так или иначе)
В своих рассуждениях ты упускаешь как минимум один очень существенный момент: форматирование в значительной
степени зависит от выбранной locale. Не предлагаешь ли ты встроить в и без того тяжеловатый std::string
работу с std::locale?
Posted via RSDN NNTP Server 1.6 RC1
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, , Вы писали:
> неужели нет хорошей и достаточно > совметимой со всем библиотеки, которая позволила бы быстро работать со > стоками и имела бы МИНИМАЛЬНЫЙ набор полезных функций???
Минимальный (и даже чуть больше) в std::string и так есть. А удовлетворяющей
все "минимальные" потребности всех библиотеки не может быть в принципе.
> МИНИМАЛЬНЫЙ — имеется в виду: поиск,
Есть.
> форматирование,
Есть, но не относится к std::string: за форматирование отвечают потоки.
В частности, поток, форматирующий в std::string называется std::ostringstream.
> изменение регистра,
Зависит от locale, а следовательно, не включено в std::string, не знающий о locale.
> корректное и простое удаление и т.д. ?
Есть.
Posted via RSDN NNTP Server 1.6 RC1
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Нет тут никакой недоделанности. Скорее, наоборот, std::string несколько перегрузили функциональностью.
d>> класс string есть d>> другие классы этой библиотеки его не использует практически нигде, d>> обычно все сводится к char* (см. exception, stringstream)
ПК>Используют. Не смешивай интерфейс и реализацию. Например, в ряде реализаций того же std::exception ПК>переданная строка хранится как std::string.
Согласен. ПК>Но вот принимать или возвращать ее ПК>в виде std::string нет никакой необходимости, достаточно const char*.
Не согласен. По двум причинам:
1) Может быть это только мое мнение, но использование двух представлений строк (const char* и string) не есть хорошая идея.
Я всегда стараюсь не использовать char* как представления строк, но если используется STL — стандартная библиотека C++ — то это просто невозможно.
2) Опять же, почему я обязан давать описание описание того же исключения как ACSII строку? Почему я не могу вернуть описание исключения как UNICODE строку?
d>> возможности использовать с уже существующем кодом минимальны (нет поступа к буфферу)
ПК>А для чего, если есть итераторы и т.п.?
Я имел в виду несколько другое. С++ — это исключительно язык программирования. Кроме языка, есть еще и среда, платформа, сторонние библиотеки и т.п.
Все это развивалось вместе с развитием самого языка.
Я ожидаю от стандартной библиотеки, чтобы она помогала осуществлять связь между языком, средой и сторонноми библиотеками.
STL же, мне кажется, больше вещь сама в себе (пусть гибкая, мощная, но сама в себе...).
Решение, когда строка вовращается при помощи заполения буфера, настолько распрастраннено в библиотеках C/C++, что
отсутствие "конструирования" строки таким способом — явное упущение STL (IMHO как всегда).
d>> функций форматирования нету (разве что опять через char* так или иначе)
ПК>В своих рассуждениях ты упускаешь как минимум один очень существенный момент: форматирование в значительной ПК>степени зависит от выбранной locale. Не предлагаешь ли ты встроить в и без того тяжеловатый std::string ПК>работу с std::locale?
Вопрос: много ли я потеряю по функциональности, есть поменяю в своей программе basic_string<char> на, скажeм, vector<char>?
В basic_string многие алгоритмы реализованы в виде методов, но многие из них (если вообще не все) реализуются при помощи внешних алгоритмов и с успехом работают для vector.
Так чего же я потеряю??? Ах, да, конечно... метод c_str() и инициализация из "ACSIIZ" строки... Печально, печально. Очень полезные методы. Но неужели это все????
Скорее всего есть еще ряд отличий, но врядли они изменять мое мнение от basic_string, а именно:
basic_string — это просто еще один контайнер в STL. За очень редким исключением, от строки в нем — только имя... А жаль.
Да, я хочу чтобы string работал с locale. Чтобы там были методы upper(), lower(), trim() и т.п.
Класс будет слишком тяжелым? А что такое тяжелый класс?
Большой размер объектов? Размер объектов вряди измениться из-за этого (хотя все будет зависить от реализации)
Скорость выполнений методов? Скорее методы можно будет реализовать даже более эффективно, чем работать через внешние конструкты.
Много методов? В добрый путь...
Сложность синтаксиса? Чтож поделаешь....
Мой вывод:
1) в STL очень неудачное название контейнера basic_string
2) в STL нет класса строк.
Сорри за категоричность моих суждений. Но, IMHO, вопрос нужно ставить именно в этой плоскости: нужен ли в STL класс basic_string в том виде, к тором он есть сейчас? Буду очень признателен, если кто-нибудь сумеет убедить меня в моей неправоте.
Здравствуйте, deviv, Вы писали:
d> 1) Может быть это только мое мнение, но использование двух d> представлений строк (const char* и string) не есть хорошая идея.
Почему?
d> 2) Опять же, почему я обязан давать описание описание того же исключения как d> ACSII строку? Почему я не могу вернуть описание исключения как UNICODE строку?
Использование UNICODE-строки в качестве аргумента для объекта исключения — не самое
лучшее решение: вообще, исключения не предназначены для отображения информации пользователю,
в крайнем случае, можно использовать какую-то таблицу для перекодировки, пользуясь строками,
содержащимися в исключениях как ключами. Но и в этом случае никакой нужды в UNICODE-содержимом
ислючений нет. А учитывая, что некоторые платформы в принципе не поддерживают UNICODE,
представить UNICODE-исключения в стандартных исключениях еще сложнее.
d> Решение, когда строка вовращается при помощи заполения буфера, настолько d> распрастраннено в библиотеках C/C++, что отсутствие "конструирования" строки d> таким способом — явное упущение STL (IMHO как всегда).
Она прекрасно умеет это делать. Только форма записи немного отличается от той,
которая нравится тебе:
std::vector<char> v (ApiGetLength());
if (!v.empty())
v.resize(ApiGetContents(&v.front(), v.size()));
return std::string(v.begin(), v.end());
d> Вопрос: много ли я потеряю по функциональности, есть поменяю в своей d> программе basic_string<char> на, скажeм, vector<char>?
и т.п.
d> Да, я хочу чтобы string работал с locale. Чтобы там были методы d> upper(), lower(), trim() и т.п.
Это излишне: все, что тебе нужно, можно реализовать, используя locale самому.
Просто форма записи будет несколько отличаться. Задача стандартной библиотеки —
предоставить функциональность. Облечь ее в удобную для тебя форму — твое право.
d> Класс будет слишком тяжелым? А что такое тяжелый класс? Большой размер объектов?
Нет, класс, в котором функциональности больше, чем нужно для работы, которую он
призван выполнять. Функциональность класса строки, предлагаемого тобой, определяется
по далеко не очевидным критериям: непонятно, почему, например, не следует включить
в него возможность перевода строк по словарю, MD5-хэширование, регулярные выражения,
кодогенерацию, и еще множество полезных "фич", нужных тому или иному проекту.
Стандартные строки, в основном, обладают простой и ясной семантикой: это класс,
представляющий собой массив символов с соответствующими утилитами. Грубо говоря,
объектно-ориентированный аналог сишных функций для работы со строками. Форматирование
же относится к вводу-выводу, как и в Си.
d> Размер объектов вряди измениться из-за этого
Конечно, изменится: в каждой строке придется хранить объект std::locale. А зачем
всем платить за функциональность, которая не нужна ни при простой работе со строками,
ни при сложной работе с locale?
d> Мой вывод: d> 1) в STL очень неудачное название контейнера basic_string d> 2) в STL нет класса строк.
Просто ты под строками понимаешь нечто свое, не то, что понимали под ними авторы стандарта.
d> IMHO, вопрос нужно ставить именно в этой плоскости: нужен ли в STL класс basic_string d> в том виде, к тором он есть сейчас?
Мне, и некоторым другим — нужен.
d> Буду очень признателен, если кто-нибудь сумеет убедить меня в моей неправоте.
Вряд ли это удастся, учитывая твой боевой настрой.
Posted via RSDN NNTP Server 1.6 RC1
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Здравствуйте, deviv, Вы писали:
d>> 1) Может быть это только мое мнение, но использование двух d>> представлений строк (const char* и string) не есть хорошая идея.
ПК>Почему?
Первое что меня часто при таком подходе удручает — наличие преобразований из одного формата в другой.
Если преобразование в const char* практически безболезненное (хотя опять же разработчики библиотеки могут и учудить), то обратное преобразование приводит в созданию лишний копии строки.
Второе, это легкость развития кода. Если вдруг потребуются глобальные изменения, единообразие в представление отдельных сущностей (будь то строки или что-то еще) очень сильно сыграет в руку.
d>> 2) Опять же, почему я обязан давать описание описание того же исключения как d>> ACSII строку? Почему я не могу вернуть описание исключения как UNICODE строку?
ПК>Использование UNICODE-строки в качестве аргумента для объекта исключения — не самое ПК>лучшее решение:
Как когда. Когда явно не самое лучшее. А когда и в самый раз.
ПК>вообще, исключения не предназначены для отображения информации пользователю,
Абсолютно не согласен. Исключение кроме того, что сигнализирует об исключительной информации должно еще и дать ключ, почему оно произошло.
И не важно куда эта информация пойдет: пользователю или в логи. Меня например, абсолюто не устаивает прочитать в логе, что мое приложение аварийно завершилось из-за "aceess denied". Что, где, почему, когда? Уж если не полные ответы, то хотя бы подсказки должны быть так же.
ПК>в крайнем случае, можно использовать какую-то таблицу для перекодировки, пользуясь строками, ПК>содержащимися в исключениях как ключами.
Как частный случай — ОК.
ПК>Но и в этом случае никакой нужды в UNICODE-содержимом ПК>ислючений нет.
ПК>А учитывая, что некоторые платформы в принципе не поддерживают UNICODE, ПК>представить UNICODE-исключения в стандартных исключениях еще сложнее.
А некоторые платформы может быть поддерживают только ACSII. Зачем когда basic_string сделан шаблоном?
d>> Решение, когда строка вовращается при помощи заполения буфера, настолько d>> распрастраннено в библиотеках C/C++, что отсутствие "конструирования" строки d>> таким способом — явное упущение STL (IMHO как всегда).
ПК>Она прекрасно умеет это делать. Только форма записи немного отличается от той, ПК>которая нравится тебе:
ПК>
Вопрос не в том, можно так сделать или нельзя. Вопрос в том как это будет выглядит и насколько эффективно....
d>> Вопрос: много ли я потеряю по функциональности, есть поменяю в своей d>> программе basic_string<char> на, скажeм, vector<char>?
ПК>Например (сигнатуры изменены для простоты):
ПК>
И какой вывод? Единственное, с чем появятся проблемы при работе с vector вместо string — это операции ввода вывода — из придется реализовавыть самим.
Функции поиска и сравнения реализуются при помощи одно или двух алгоритмов.
d>> Да, я хочу чтобы string работал с locale. Чтобы там были методы d>> upper(), lower(), trim() и т.п.
ПК>Это излишне: все, что тебе нужно, можно реализовать, используя locale самому. ПК>Просто форма записи будет несколько отличаться. Задача стандартной библиотеки — ПК>предоставить функциональность. Облечь ее в удобную для тебя форму — твое право.
Наличие метод compare(), substr(), replace() и т.п. свидетельствует о том, что определенная функциональность все-таки была облечена в удоьную форму.
d>> Класс будет слишком тяжелым? А что такое тяжелый класс? Большой размер объектов?
ПК>Нет, класс, в котором функциональности больше, чем нужно для работы, которую он ПК>призван выполнять. Функциональность класса строки, предлагаемого тобой, определяется ПК>по далеко не очевидным критериям: непонятно, почему, например, не следует включить ПК>в него
ПК>возможность перевода строк по словарю,
есть std:map. И я сложно представляю себе, как подобную функциональность можно реализовать проще для использования в самом классе строки, чем во внешнем классе. ПК>MD5-хэширование
Идея хорошая, только ее надо обобщить: пусть будет метод который принимает функтор для выполнения хеширования. Только этот метод будет отличаться от сооветствующего алгоритма только порядком символов при его вызове: s.hash(MD5()) или hash(s, MD5()) ПК>, регулярные выражения,
Поддержка регулярных выражений (внешняя или внутреняя) — обязательно. ПК>кодогенерацию,
... не совсем понял ПК>и еще множество полезных "фич", нужных тому или иному проекту.
фич конечно же много. Те или иные останутся неудел
ПК>Стандартные строки, в основном, обладают простой и ясной семантикой: это класс, ПК>представляющий собой массив символов с соответствующими утилитами.
К сожалению, Вы правы. А хотелось бы: это класс, представляющий тип данных для хранения и манипулирования строками. ПК>Грубо говоря, ПК>объектно-ориентированный аналог сишных функций для работы со строками. Форматирование ПК>же относится к вводу-выводу, как и в Си.
Хм... Вы меня натолкнули на замечательную идею: нужно реализовать набор операторов << для форматирования непосредственно строк, миную потоки.
И как я раньше до этого не додумался!? d>> Размер объектов вряди измениться из-за этого
ПК>Конечно, изменится: в каждой строке придется хранить объект std::locale. А зачем ПК>всем платить за функциональность, которая не нужна ни при простой работе со строками, ПК>ни при сложной работе с locale?
При данной организации std::locale — безусловно. Но этот выриант не единственный.
d>> Мой вывод: d>> 1) в STL очень неудачное название контейнера basic_string d>> 2) в STL нет класса строк.
ПК>Просто ты под строками понимаешь нечто свое, не то, что понимали под ними авторы стандарта.
Опять я к сожелению вынужден признать Вашу правоту
d>> IMHO, вопрос нужно ставить именно в этой плоскости: нужен ли в STL класс basic_string d>> в том виде, к тором он есть сейчас?
ПК>Мне, и некоторым другим — нужен.
А если поставить вопрос по-другому, если бы было два класса string: первый такой какой есть сейчас, а второй примерно такой, какой я хочу. Каким бы классом пользовался народ? Безусловно, кое-кто бы предпочел первый, но и многие обрадовались бы второму.
d>> Буду очень признателен, если кто-нибудь сумеет убедить меня в моей неправоте.
ПК>Вряд ли это удастся, учитывая твой боевой настрой.
Здравствуйте, deviv, Вы писали:
D>Абсолютно не согласен. Исключение кроме того, что сигнализирует об исключительной информации должно еще и дать ключ, почему оно произошло. D>И не важно куда эта информация пойдет: пользователю или в логи. Меня например, абсолюто не устаивает прочитать в логе, что мое приложение аварийно завершилось из-за "aceess denied". Что, где, почему, когда? Уж если не полные ответы, то хотя бы подсказки должны быть так же.
А кто мешает эти подсказки давать? Просто, вместо форматирования сообщения типа "MyCoolErrorDescription (code) "__FILE__ " "__LINE__"!" стоит все-таки использовать что-то более структурированное (например, таблицу с шаблонами для отображения параметров исключения по коду — тут и интернациолизация тебе, и полная свобода использования любых наборов символов и способов отображения, и все такое. А исключения "всего-лишь" предназначены для обработки ошибок. никак не для форматирования строк (шутка) Короче, состав строки исключения не предназначен для прямого отображения (что и написано выше Павлом).
ПК>>в крайнем случае, можно использовать какую-то таблицу для перекодировки, пользуясь строками, ПК>>содержащимися в исключениях как ключами.
D>Как частный случай — ОК.
Это — не частный случай. Это самый правильный и общепринятый подход. Ты никогда не задумывался, зачем в виндовых exe-шниках ресурсы придумали? Ни один GUI (хороший) не настраивается строками, представление которых зашито в код. Это должно быть для тебя хорошим оппонирующим аргументом в споре об исключениях. Так-что, твое "абсолютно несогласен", похоже, относится только к консольному программированию с английским в роли единственного языка Хотя нет, ты говорил про UNICODE. Но, как я описал — это плохой путь. От него почти все уже отказались .
D>И какой вывод? Единственное, с чем появятся проблемы при работе с vector вместо string — это операции ввода вывода — из придется реализовавыть самим. D>Функции поиска и сравнения реализуются при помощи одно или двух алгоритмов.
Как насчет insert, replace, += в конце концов? Ведь кроме алгоритма есть и еще характеристики... Например, производительность.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, MaximE, Вы писали:
А>>> string s(""); А>>> GetWindowText(...???...);
ME>>Используй std::vector<> или MFC/ATL CString.
А>>> ...И еще один маленький вопросик, как можно отформатировать эту строку?.. Конечно, если получить доступ к буферу, то вопрос снимается — sprintf, а есть ли встроенный метод, что-то я его не нашел. Спасибо!
ostringstream ost;
ost << "formated text " << setfill(' ') << setw (3) << 10 ;
string s = ost.str();
А> А в чем тогда вообще смысл этого string, если для вызова ЛЮБОЙ функции нужно вводить дополнительные типы?????????? Бред!? А> Например, сейчас мне нужно вызвать CharLower для string... Это что ж мне нужно объявлять char * перегонять туда стринг и опять обратно????? :\
string s("TeXt");
transform(s.begin(),s.end(),s.begin(),tolower);
cerr << s << endl;
А> Плохо выразился. Я имел в виду что-то сделанное на основе char * так, чтобы это было легко применять и в MFC и в ATL и в WTL. А> Просто мне не совсем понятно, зачем было писать string, если он, в принципе, недоделан до того, чтобы его можно было легко использовать. Иногда он усложняет жизнь, а не упрощает! ...
Я думаю это объясняется тем, что STL делали ярые юниксоиды, поэтому они по меньшей мере не стремились, а скорее всего специально (из вредности) сделали так, чтобы STL было неудобно применять в MFC, в ATL и в WTL.
Здравствуйте, SWW, Вы писали:
SWW>Удивительно: всем это кажется более удобным, но разработчики STL почему-то так не считают
Всем? Ты тоже так считаешь? Ну на тебе кусок кода, разбирайся:
SomeString s;
...
s = (const char*)s;
Как успехи?
Потом, "всем" кажется реализация с подсчетом ссылок очень желательной. Но в многопоточном окружении начинаются проблемы с ее использованием. Интерфейс класса их позволяет озбнжать, т.к. содержит необходимые блокировки. Но как-только добавляется подсчет оператор преобразования (возвращающий физический буффер) — Boom!!! (искры в разные стороны).
Ведь ни у кого не вызывает негодования, что объекты ядра в OS адресуются не прамыми адресами, а косвенными (дескрипторами). Это не мешает в большинстве случаев, и помогает в большом. А если это так, то почему же "всем" кажется более удобным то, что потенциально опасно? Наверное, такова природа человека
Здравствуйте, SWW, Вы писали:
SWW>Я думаю это объясняется тем, что STL делали ярые юниксоиды, поэтому они по меньшей мере не стремились, а скорее всего специально (из вредности) сделали так, чтобы STL было неудобно применять в MFC, в ATL и в WTL.
То есть, ты обвиняешь международный коммитет по стандартизации в приверженности к конкретной ветке операционных систем? Самому не смешно? К тому-же, не знаю, как ATL, а WTL еще и в планах не было, когда STL появилась.
Здравствуйте, Kaa, Вы писали:
Kaa>Здравствуйте, SWW, Вы писали:
SWW>>Я думаю это объясняется тем, что STL делали ярые юниксоиды, поэтому они по меньшей мере не стремились, а скорее всего специально (из вредности) сделали так, чтобы STL было неудобно применять в MFC, в ATL и в WTL.
Kaa>То есть, ты обвиняешь международный коммитет по стандартизации в приверженности к конкретной ветке операционных систем? Самому не смешно? К тому-же, не знаю, как ATL, а WTL еще и в планах не было, когда STL появилась.
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
Какой нафиг ATL?
// This is a part of the Active Template Library.
// Copyright (C) 1996-1998 Microsoft Corporation
// All rights reserved.
Здравствуйте, Kaa, Вы писали:
Kaa>Здравствуйте, deviv, Вы писали:
Kaa>А кто мешает эти подсказки давать? Просто, вместо форматирования сообщения типа "MyCoolErrorDescription (code) "__FILE__ " "__LINE__"!" стоит все-таки использовать что-то более структурированное (например, таблицу с шаблонами для отображения параметров исключения по коду — тут и интернациолизация тебе, и полная свобода использования любых наборов символов и способов отображения, и все такое. А исключения "всего-лишь" предназначены для обработки ошибок. никак не для форматирования строк (шутка) Короче, состав строки исключения не предназначен для прямого отображения (что и написано выше Павлом).
ПК>>>в крайнем случае, можно использовать какую-то таблицу для перекодировки, пользуясь строками, ПК>>>содержащимися в исключениях как ключами.
D>>Как частный случай — ОК. Kaa>Это — не частный случай. Это самый правильный и общепринятый подход. Ты никогда не задумывался, зачем в виндовых exe-шниках ресурсы придумали? Ни один GUI (хороший) не настраивается строками, представление которых зашито в код. Это должно быть для тебя хорошим оппонирующим аргументом в споре об исключениях. Так-что, твое "абсолютно несогласен", похоже, относится только к консольному программированию с английским в роли единственного языка Хотя нет, ты говорил про UNICODE. Но, как я описал — это плохой путь. От него почти все уже отказались .
Использование строк напрямую в исключениях и использование ключей — это частные случаи использования исключений. Оба решения имеют право на жизнь.
А реально наибольшей гибкостью обладает "смещанное" решение: шаблоны сообщений хранятся где-либо отдельно, а подстановка конкретных параметров в сообщения вставляются по месту выкидывания этого исключения. В этом случае основную роль будет играть форматирование строки.
Ко всему прочему в C++ исключения прилеплены так, чтобы как всегда оказать наименьшее влияние на существующий код. Т.е. опять не сделано то, что можно было бы. А именно идентификация места выброса исключения, а еще лучше стек раскрутки исключения. Но имеем, то что имеем. Если стек раскрутки исключения реализовать пользовательскими средствами проблематично, то идентифицировать место выброса еще кое как можно: __FILE__, __LINE__. Но опять получается целая система макросов.... Неудобно все это, хотя и работает.
D>>И какой вывод? Единственное, с чем появятся проблемы при работе с vector вместо string — это операции ввода вывода — из придется реализовавыть самим. D>>Функции поиска и сравнения реализуются при помощи одно или двух алгоритмов.
Kaa>Как насчет insert, replace, += в конце концов?
Kaa>Ведь кроме алгоритма есть и еще характеристики... Например, производительность.
Безусловно. Гораздо приятнее когда replace выполняет быстрее. Но и неменее приятно, когда и trim тоже не тормозит
ПК>Минимальный (и даже чуть больше) в std::string и так есть. А удовлетворяющей ПК>все "минимальные" потребности всех библиотеки не может быть в принципе.
>> МИНИМАЛЬНЫЙ — имеется в виду: поиск,
ПК>Есть.
Рассуждения замечательные. Я тоже хотел бы видеть стандартную библиотеку как некий полуфабрикат, содержащий минимальный набор функций, которые необходиму всем, а те функции, которые нужны конкретным программистам, они напишут сами. И я поначалу не счел большим неудобством отсутствие operator(const char*) — какие проблемы, сейчас создадим свой класс MyString используя в качестве базового std::string и добавим туда все что мне надо. Но не тут-то было! ВСЕ классы STL не предназначены для использования в качестве базового! Вероятно их авторы считают свои классы истиной в последней инстанции. Подобной самоуверенности даже Микрософт позавидует.
>> форматирование,
ПК>Есть, но не относится к std::string: за форматирование отвечают потоки. ПК>В частности, поток, форматирующий в std::string называется std::ostringstream.
Перепишите мне строку из реальной программы используя форматирование потоков:
Здравствуйте, SWW, Вы писали:
А>> Плохо выразился. Я имел в виду что-то сделанное на основе char * так, чтобы это было легко применять и в MFC и в ATL и в WTL. А>> Просто мне не совсем понятно, зачем было писать string, если он, в принципе, недоделан до того, чтобы его можно было легко использовать. Иногда он усложняет жизнь, а не упрощает! ...
SWW>Я думаю это объясняется тем, что STL делали ярые юниксоиды, поэтому они по меньшей мере не стремились, а скорее всего специально (из вредности) сделали так, чтобы STL было неудобно применять SWW>в MFC, в ATL и в WTL.
в любой библиотеке, ориентированной на представление строки как char*
Но ни в коей мере не было целью. Философия STL определяется философией развития языка С++:
если в языке уже есть конструкт F и стоит выбор какой новый конструкт добавить A или B, то
если F(A) === B, то одназначно делается выбор в пользу A.
В данном случае: F — явное преобразование типа, А -> c_str(), B -> operator const char*()
В руки программиста дается бОльший контроль за программой, но это требует от него ряда дополнительных действий.
Здравствуйте, SWW, Вы писали:
SWW>Рассуждения замечательные. Я тоже хотел бы видеть стандартную библиотеку как некий полуфабрикат, содержащий минимальный набор функций, которые необходиму всем, а те функции, которые нужны конкретным программистам, они напишут сами. И я поначалу не счел большим неудобством отсутствие operator(const char*) — какие проблемы, сейчас создадим свой класс MyString используя в качестве базового std::string и добавим туда все что мне надо. Но не тут-то было! ВСЕ классы STL не предназначены для использования в качестве базового! Вероятно их авторы считают свои классы истиной в последней инстанции. Подобной самоуверенности даже Микрософт позавидует.
Все бы было не так плохо, если бы в C++ было реализовано наследование конструкторов.
Никто не знает предисторию, почему это не было реализовано?
V> А оно и не заточено вовсе под работу с GetWindowText() или ещё подобным чем-то. Оно вообще-то, и не знает о существовании WindowsAPI.
Ну так об этом-то и говорят! Или тот факт, что оно не заточено под работу с GetWindowText() является оправданием и тем самым доказывает что его нужно использовать для работы с GetWindowText()?
Ты считаешь, что если бы в std::string был operator(const char*) то я бы без труда понял, что означает твой идентификатор SomeString? Не улавливаю связи...
Здравствуйте, SWW, Вы писали:
D>>Все бы было не так плохо, если бы в C++ было реализовано наследование конструкторов.
SWW>А также деструкторы всегда должны быть виртуальными.
Ну если говорить об переопределении поведения класса через наследование, то в STL все плохо:
ни тебе виртуальных деструкторов, ни вообще никаких виртуальных методов. Все методы или public, или private.
И даже если что-нибудь попадется protected, так это часть реализации не регламентированная в стандарте.
Единственное, что можно сделать через наследование — добавить некую функциональность. Но когда видишь десяток конструкторов — все жедание сразу пропадает...
А> Помогите, пожалуйста, начинающему разобраться
А> Что-то я не пойму до конца всю прелесть типа string. А> Как мне получить доступ к самомоу буферу? Ведь c_str() возвращает константу :\ А> Например, как мне использовать тип string для получения текста окна?
А> string s(""); А> GetWindowText(...???...);
а так не поможет
s.resize(1000,' ');
GetWindowText(S.c_str(),s.length());
Здравствуйте, deviv, Вы писали:
D>2) Опять же, почему я обязан давать описание описание того же исключения как ACSII строку? Почему я не могу вернуть описание исключения как UNICODE строку?
Потому что есть базовый класс всех исключений — exception, который хочет именно ASCII строку.
Но, если так хочется передавать UNICODE строки средствами стандартных классов исключений — перекодируй из в UTF-8
Реально же, исключения вообще не должны содержавть какой-либо текст. В них нужно хранить: Код (идентификатор) ошибки, по которому можно найти шаблон сообщения
Параметры для формирования сообщения
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Здравствуйте, deviv, Вы писали:
D>>2) Опять же, почему я обязан давать описание описание того же исключения как ACSII строку? Почему я не могу вернуть описание исключения как UNICODE строку?
КД>Потому что есть базовый класс всех исключений — exception, который хочет именно ASCII строку.
А почему он хочет именно ASCII? Причина? Чем ASCII лучше другого представления строк?
КД>Но, если так хочется передавать UNICODE строки средствами стандартных классов исключений — перекодируй из в UTF-8
А хочу гибкости. А раз ее меня лишают, то пытаюсь понять ради чего?
КД>Реально же, исключения вообще не должны содержавть какой-либо текст. В них нужно хранить: КД> КД>Код (идентификатор) ошибки, по которому можно найти шаблон сообщения КД>Параметры для формирования сообщения КД>
Тогда для чего там метод what()? Чтобы по коду найти сообщение об ошибке, подставить в него параметры?
Затем перекодировать в UTF-8 (например), вернуть const char* наружу, что его там же снова перекодировали в UNICODE и записали в лог или отобразили на экран?
Здравствуйте, voxel3d, Вы писали:
V> У тебя со временем что-то не сходится.. То три месяца назад, то через год...
На самом деле эта история началась 3 года назад и продолжается до сих пор (окончатель запутал со временем ?
V> Вывод: со стандартной библиотекой если нормально всё выучить, можно работать вполне нормально, а недоучившись, оно, конечно, через это самое место. Недоучившись, потом и задаются дурацкие вопросы -- а нахрен надо было такие строки писать??
А что кому-то удавалось "нормально ВСЕ выучить"? Потом, я не понял в чем претензия: в вопросе топика? (нормальный вопрос, хотя это и не мое дело) или в моем ответе? (рассказал про себя, поскольку был в свое время также неприятно удивлен этой особенностью стандартного string)
V> А оно и не заточено вовсе под работу с GetWindowText() или ещё подобным чем-то. Оно вообще-то, и не знает о существовании WindowsAPI.
Т.е. если прога под Win32, то лучше о нем забыть...
Здравствуйте, deviv, Вы писали:
D>Тогда для чего там метод what()? Чтобы по коду найти сообщение об ошибке, подставить в него параметры?
Вот ты вбил себе в голову, что пользователю нужно отобразить именно то, что возращает what и теперь мечешься — а как мне вывести юзеру что-то другое. Исходя из своео небольшого опыта — стандарные исключения должны использоваться только для перехвата нештатных ситуаций. Ну типа нехватка памяти, выход за пределы диапазона и т.д.
На прикладном уровне нужно генерировать свои классы исключений, производные от exception.
Ты перехватываешь все исключения
catch(exception&)
а потом через dynamic_cast анализируешь, что и именно ты поймал и как его нужно обработать.
Обрати внимание на реализацию OLEDB_ProcessErrorException. Если она не смогла понять что это за исключение, то только тогда она лезет к exception::what()
понятно, что это не предназначено для написания маленьких программ. Но в больших программах, думается, всё именно так и делается.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, deviv, Вы писали:
D>Здравствуйте, icWasya, Вы писали:
W>>Здравствуйте, Аноним, Вы писали:
А>>> string s(""); А>>> GetWindowText(...???...);
W>>а так не поможет W>> s.resize(1000,' '); W>> GetWindowText(S.c_str(),s.length());
D>Чтобы это откомпилировалось нужен const_cast. D>Ну а чтобы это всегда стабильно работало — извините, не получится....
ну тогда так
string s;
S.resize(GetWindowTextLength(Memo1->Handle),' ');
GetWindowText(Memo1->Handle,(char*)S.c_str(),S.length());
>> ......чтобы это всегда стабильно ......
и в чём тут проблема? — если только неправильно учитывать размер буфера — так ведь ничего не поможет
Здравствуйте, icWasya, Вы писали:
W> и в чём тут проблема? — если только неправильно учитывать размер буфера — так ведь ничего не поможет
Проблема в том, что c_str() не обязан возвращать непосредственно буфер. Это остается в компетенции разработчика библиотеки.
Точко также, факт того, что c_str() возвращает ZERO-terminated строку не обязывает хранить представление строки именно в этом формате.