Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > CString to const char*


Автор: tilser 21.3.2009, 21:59
Вариант 1:
Код

    char * buff = new char[255];
    buff = "Help me with unicode!!!";

Получаем: user posted image

Вариант 2:
Код

    CString str("Help me with unicode!!!");
    char * buff = new char[255];
    buff = (char*)str.GetBuffer();

Получаем: user posted image
Такая туфтень только в юникоде. В мультибайте все окей.



Нужно скопировать  из CString () или LPTSTR строчку в char*, целиком. 
Хэлп, как говорится!

Автор: Helmet 21.3.2009, 22:18
http://msdn.microsoft.com/en-us/library/aa450989.aspx

Автор: tilser 21.3.2009, 23:02
Helmet, спасибо.
Правда я уже для себя нашел решение.

Вот такую ф-цию написал:
Код

const char* CStringToConstChar(CString SourceString)
{
    char *str = new char[strlen((char*)SourceString.GetBuffer())];
    for(int i = 0; i < SourceString.GetLength(); i++)
        str[i] = SourceString.GetAt(i);
    return str;
}

 smile 

Автор: Rififi 22.3.2009, 00:07
CStringW str1 = L"текст в юникоде";
CStringA str1 =  CW2A(str1);

Автор: Helmet 22.3.2009, 00:32
tilser, ваша функция не будет работать правильно при включенном юникоде. Вообще то она будет неправильно работать и при выключенном (т.к. нет завершающего нуля), но это другая история.
Почему вы в первом случае так извращенно (причем неправильно) определяете длину строки, а во втором показываете, что умеете нормально это делать (CString::GetLength). При включенном юникоде у вас CString::GetAt вернет wchar_t, размер которого 2 байта, а вы его в однобайтовый char суете. А потом вы просто убили. Возвращаете константный указатель на выделенную память, а кто и как чистить ее будет подумали?
Все же рекомендую присмотреться к стандартной WideCharToMultiByte или же, если есть возможность узать ATL в проекте, обратить внимание на пост Rififi.

Автор: tilser 22.3.2009, 17:51
Helmet, спасибо за объяснение.
Во что получилось:
Код

CString str("Help me with unicode!!!");
int len = str.GetLength();
char *buff = new char[len+1]; 
WideCharToMultiByte(CP_ACP, 0, str.GetBuffer(), -1, buff, len, NULL, NULL);


user posted image

Как от этого мусора избавиться? Мне нужно точно то, что было на первом скриншоте.

Автор: Rififi 22.3.2009, 18:45
Как от этого мусора избавиться?
ты хоть раз в жизни сам мусор из дома выносил? smile 
в программировании на C++ то же самое: мусор сам не исчезает, о нём надо позаботиться.
char *buff = new char[len+1]();

Автор: Helmet 22.3.2009, 20:10
Во держи 2 функции. Надеюсь все понятно будет
Код

char * unicodeToAnsi(const wchar_t * string)
{
    int size = WideCharToMultiByte(CP_ACP, 0, string, -1, 0, 0, 0, 0);
    if(size == 0)
    {
        return 0;
    }
    char * out = new char[size];
    WideCharToMultiByte(CP_ACP, 0, string, -1, out, size, 0, 0);
    return out;
}

char * getAnsiString(const TCHAR * string)
{
    char * out = 0;
#ifdef _UNICODE
    out = unicodeToAnsi(string);
#else
    out = new char[strlen(string) + 1];
    strcpy(out, string);
#endif
    return out;
}


Использовать их следует так:
1 случай. Тебе нужно просто конвертировать Unicode строку в Ansi.
Код

wchar_t * unicode = L"Привет";
char * ansi = unicodeToAnsi(unicode);
// здесь что то делаем
delete [] ansi; // не забываем чиститься

2 случай. Тебе нужно независимо от настроек получить Ansi строку.
Код

CString string = TEXT("Привет");
char * ansi = getAnsiString(string);
// здесь что то делаем
delete [] ansi; // не забываем чиститься

Автор: tilser 22.3.2009, 22:06
Helmet, еще раз спасибо! smile 

Автор: Helmet 22.3.2009, 22:12
Пожалуйста   smile 
Тему решенной не забываем помечать  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)