Я рекомендую вариант с std::string.
Почему?
1. Входит в стандарт — будет работать на любом совместимом компиляторе
2. Является частью стандартной библиотеки — сочетается со стандартными алгоритмами
Да здравствует мыло душистое и веревка пушистая.
Re: удобное и функциональное использование строки в C++
Speakus пишет: > Подскажите, пожалуйста, какой класс лучше использовать для строк?
Ответа на ваш вопрос нет и быть не может. Потому что "зависит от"
многих-многих факторов. В первом приближении это должно быть std::string,
если у вам не будет проблем с производительностью.
Posted via RSDN NNTP Server 2.1 beta
Re: удобное и функциональное использование строки в C++
include <string>
std::string
include <atlstr.h>
CString
S>Ну и конечно же — почему именно этот?
А для чего тебе нужны строки? Что за операции над ними ты планируешь делать? Как часто порождать/разрушшать и т. д.?
Конкретно два приведённых тобой варианта отличаются AFAIK примерно следующим
1) Удобстовом использования вместо const char*
2) Безопасностью того же
3) Возможностью получить из char*-API строку непосредсвенно внутрь буфера строки\
4) Возможностью организовать строку любых копибл элементов
и т. д.
Если строка тебе нужна несколько раз за программу, то всё равно кукую использовать
Если строка тебе нужна именно как строка, а не как stl-контейнер (то есть если ты не хранишь в строках, например, аттрибутиванные буквы, не используешь всякие алгоритмы вроде std::sort), то проще наверное пользоваться ATL строкой.
Если тебе важно переносимость и прочие выгоды стандартизации, то проще STL-строкой
Ну а если строки это главная или одна из главных структур данных в твоей сложной программе, то, скорее всего, прийдётся написать свою строку
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: удобное и функциональное использование строки в C++
От:
Аноним
Дата:
02.10.07 08:55
Оценка:
Здравствуйте, Speakus, Вы писали:
S>Здравствуйте, S>Подскажите, пожалуйста, какой класс лучше использовать для строк? S>include <string> S>std::string
S>include <atlstr.h> S>CString
S>Может какой-то другой? А есть ли другие? S>Ну и конечно же — почему именно этот?
По крайней мере несколько раз встречал некорректное поведение класса CString (MFC, MSVC 6.0) при присваивании значения (операторы = и +=), поэтому в средних и больших проектах скорее всего буду использовать std::string и std::wstring.
Re: удобное и функциональное использование строки в C++
Здравствуйте, Speakus, Вы писали:
S>Здравствуйте, S>Подскажите, пожалуйста, какой класс лучше использовать для строк? S>include <string> S>std::string
S>include <atlstr.h> S>CString
S>Может какой-то другой? А есть ли другие? S>Ну и конечно же — почему именно этот?
имхо, юзал бы std::string , но как то приходилось реализовать свой класс строки,
чисто для своих нужд, без всяких излишеств, с обрезаным функционалом.
Re[2]: удобное и функциональное использование строки в C++
Здравствуйте, Аноним, Вы писали:
А>По крайней мере несколько раз встречал некорректное поведение класса CString (MFC, MSVC 6.0) при присваивании значения (операторы = и +=)
А можно рассказать поподробнее? Что за проблемы, в каких контекстах?
Как-то странно, строка вещь часто используемая, должна бы быть отлажена...
Так что все косяки хочется знать
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: удобное и функциональное использование строки в C++
А>>По крайней мере несколько раз встречал некорректное поведение класса CString (MFC, MSVC 6.0) при присваивании значения (операторы = и +=) E>А можно рассказать поподробнее? Что за проблемы, в каких контекстах?
проблема может быть в неявных преобразованиях строки в указатель на нижележащий тип,
что может вызывать побочные эффекты
Здравствуйте, Awaken, Вы писали:
A>проблема может быть в неявных преобразованиях строки в указатель на нижележащий тип, A>что может вызывать побочные эффекты
Приведи пример.
Что-то типа:
CString str;
str += stsstr( str, str );
или как-то иначе?
О чём идёт речь?
Казалось бы оба оператора ничего никуда не приводят, а просто приписывают в строку новое значение, или приписывают его в конец строки.
Единственный путь глюков, который я тут вижу, это сослаться на конец строки припомощи const char*, да этот вот указатель и передать в += того же объекта.
Ну там
CString str = "idfhkdsfjv";
const char* text = str;
str += text + str.Length() / 2;
Такой какой-то контекст?
Но это же понятно, что так писать нехорошо и опасно...
А как такая проблема может возникнуть в нормальном коде?
Или проблема вообще какая-то другая.
Скажем такая:
CString str;
if( str ) {
std::cout << "Ленин всегда с тобой, Ленин всегда живой...\n";
}
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
A>>проблема может быть в неявных преобразованиях строки в указатель на нижележащий тип, A>>что может вызывать побочные эффекты
E>Приведи пример.
s = s1 - s2 + s3;
// ↑ ой, должен был быть «+»
// а на самом деле это эквивалентно:
s = CString(LPCTSTR(ptrdiff_t(LPCTSTR(s1) - LPCTSTR(s2)) + LPCTSTR(s3)));
Или просто delete CString(). Или if(CString()) { }.
Здравствуйте, Roman Odaisky, Вы писали:
E>>Приведи пример.
RO>
RO>s = s1 - s2 + s3;
RO>// ↑ ой, должен был быть «+»
RO>// а на самом деле это эквивалентно:
RO>s = CString(LPCTSTR(ptrdiff_t(LPCTSTR(s1) - LPCTSTR(s2)) + LPCTSTR(s3)));
RO>
А что такое CString( int )?
RO>Или просто delete CString(). Или if(CString()) { }.
Вот с if я ещё понимаю, но это же просто клиника, так писать. А с delete, ИМХО, не страшно.
Так как delete в программах вообще аккуратно надо использовать, никто тебе не мешает ещё как-нибудь не то удалить, скажем так:
std::string str;
delete &str;
...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: удобное и функциональное использование строки в C++
Здравствуйте, Erop, Вы писали:
E>А для чего тебе нужны строки? Что за операции над ними ты планируешь делать? Как часто порождать/разрушшать и т. д.?
E>Конкретно два приведённых тобой варианта отличаются AFAIK примерно следующим E>1) Удобстовом использования вместо const char* E>2) Безопасностью того же E>3) Возможностью получить из char*-API строку непосредсвенно внутрь буфера строки\ E>4) Возможностью организовать строку любых копибл элементов E>и т. д.
E>Если строка тебе нужна несколько раз за программу, то всё равно кукую использовать E>Если строка тебе нужна именно как строка, а не как stl-контейнер (то есть если ты не хранишь в строках, например, аттрибутиванные буквы, не используешь всякие алгоритмы вроде std::sort), то проще наверное пользоваться ATL строкой. E>Если тебе важно переносимость и прочие выгоды стандартизации, то проще STL-строкой E>Ну а если строки это главная или одна из главных структур данных в твоей сложной программе, то, скорее всего, прийдётся написать свою строку
Спасибо.
по пунктам
2) — вроде как в параллельной ветке так и не нашли причин опасности этого пункта — или имеется в виду что-то другое?.
3) — тоже не ясно
про стандартизацию — понял. Конечно лучше со стандартизацией чем без.
1) Скажите а нет ли возможности заставить работать string c const char* (ну т.е. получить выгоду пункта 1 — не теряя возможности использования GNU компиляторов) ?
пробовал двумя способами:
class mystring: public std::string
{
public:
mystring(const std::string & x) {*this = x;}
operator const char*() const {return this->c_str();}
};
и
operator const char*(const std::string &x) {return x.c_str();}
второй случай вообще не компилируется — нельзя видать делать преобразование типов не своего класса.
Хотелось бы чтобы код подобный этому работал:
mystring var("x");
_putenv("myvar=" + var); //здесь происходит преобразование типа в std::string результирующей строки — а она уже в const char * автоматом преобразовываться не умеет.
или как-то иначе?
Извините, а какая здесь проблема?
E>О чём идёт речь? E>Казалось бы оба оператора ничего никуда не приводят, а просто приписывают в строку новое значение, или приписывают его в конец строки. E>Единственный путь глюков, который я тут вижу, это сослаться на конец строки припомощи const char*, да этот вот указатель и передать в += того же объекта. E>Ну там
CString str = "idfhkdsfjv";
E>const char* text = str;
E>str += text + str.Length() / 2;
E>Такой какой-то контекст? E>Но это же понятно, что так писать нехорошо и опасно...
И здесь не могли бы объяснить почему так писать не хорошо? str.Length() — не компилится кстати
E>А как такая проблема может возникнуть в нормальном коде? E>Или проблема вообще какая-то другая. E>Скажем такая:
CString str;
E>if( str ) {
E> std::cout << "Ленин всегда с тобой, Ленин всегда живой...\n";
E>}
а что подразумевается под if (str) ? разве это нормальное использование класса? а почему кстати тут не генерируется сообщения об ошибке C2451 ?
Re[2]: удобное и функциональное использование строки в C++
Здравствуйте, Awaken, Вы писали:
S>>Может какой-то другой? А есть ли другие? S>>Ну и конечно же — почему именно этот?
A>есть еще QString, XMLString и т.д.
MSDN о них не в курсе — самописные что ли?
Re[3]: удобное и функциональное использование строки в C++
От:
Аноним
Дата:
03.10.07 11:11
Оценка:
Здравствуйте, Erop, Вы писали:
E>А можно рассказать поподробнее? Что за проблемы, в каких контекстах? E>Как-то странно, строка вещь часто используемая, должна бы быть отлажена... E>Так что все косяки хочется знать
Пожалуйста, без слипа у меня правильно работает через 2 — 3 раза
BOOL CReg::GetArray(CString strValueName, void * pArr, size_t sizeArr)
{
if(pArr && sizeArr && strValueName.GetLength())
{
CString strSK;
GetSubKeyString(strSK);
//
// it is essential to call Sleep(0) here
// because there is seems to be a bug in MSVC,
// and without Sleep(0) call
// functions GetSubKeyString && GetArray
// will not work properly
//
Sleep(0);
return GetArray(CReg::HKCU,
(LPCTSTR)strSK,
(LPCTSTR) strValueName,
pArr,
sizeArr);
}
return FALSE;
}
BOOL CReg::GetSubKeyString(CString& str)
{
CString s;
str = _T("Software\\");
str += CMfcieApp::_strRegKey;
str += _T("\\");
s.LoadString(AFX_IDS_APP_TITLE);
str += s;
str += _T("\\");
str += this->_strSubSectionName;
return TRUE;
}
Re[4]: удобное и функциональное использование строки в C++
От:
Аноним
Дата:
03.10.07 11:17
Оценка:
Здравствуйте, Аноним, Вы писали: А>Пожалуйста, без слипа у меня правильно работает через 2 — 3 раза
{}
ЗЫ
Вызывается это в InitInstance()
Re[3]: удобное и функциональное использование строки в C++
Здравствуйте, Speakus, Вы писали:
S>1) Скажите а нет ли возможности заставить работать string c const char* (ну т.е. получить выгоду пункта 1 — не теряя возможности использования GNU компиляторов) ?
А оно точно надо? Выгода очень сомнительна (С VisualAssist и ему подобными так вообще пофигу), а недостатки налицо.
Может стоит озаботиться решаемой задачей, а не играться в бирюльки..
Re[3]: удобное и функциональное использование строки в C++
Здравствуйте, Speakus, Вы писали:
E>>Конкретно два приведённых тобой варианта отличаются AFAIK примерно следующим E>>1) Удобстовом использования вместо const char* E>>2) Безопасностью того же E>>3) Возможностью получить из char*-API строку непосредсвенно внутрь буфера строки\ E>>4) Возможностью организовать строку любых копибл элементов E>>и т. д.
E>>Если строка тебе нужна несколько раз за программу, то всё равно кукую использовать E>>Если строка тебе нужна именно как строка, а не как stl-контейнер (то есть если ты не хранишь в строках, например, аттрибутиванные буквы, не используешь всякие алгоритмы вроде std::sort), то проще наверное пользоваться ATL строкой. E>>Если тебе важно переносимость и прочие выгоды стандартизации, то проще STL-строкой E>>Ну а если строки это главная или одна из главных структур данных в твоей сложной программе, то, скорее всего, прийдётся написать свою строку
S>2) — вроде как в параллельной ветке так и не нашли причин опасности этого пункта — или имеется в виду что-то другое?.
Ну, например, тот же самый if( str )...
Ну и вообще, лёгкость неявного получения из объекта const char* многими рассматривается, как источник опасности. Типа нужно редко, а вредит часто. Некоторые наоборот считают, что это надо и удобно... S>3) — тоже не ясно
Ну вот есть у тебя API функция какакя-то, скажем GetUserName( char*, UINT* count ).
Вот хочешь ты получить из неё результат сразу в строку.
С одной строкой ты пишешь так
CString str;
UINT len = MAX_USER_NAME_LENGTH;
GetUserName( str.GetBuffer( len ), &len );
str.Release( len );
А с другой прийдётся использовать промежуточный буффер, как-то так:
vector<char> buffer;
UINT len = MAX_USER_NAME_LENGTH;
buffer.set_size( len + 1 );
GetUserName( &buffer[0], &len );
buffer.set_size( len );
buffer.push_back( 0 );
string str = &buffer[0]; // типа лишнее копирование :(
S>Хотелось бы чтобы код подобный этому работал: S>_putenv("myvar=" + var); //здесь происходит преобразование типа в std::string результирующей строки — а она уже в const char * автоматом преобразовываться не умеет.
Ну так string специально так спроектирована, чтобы обломать тебя
Тока так:
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском