Как преобразовать CString в char* (char[]) ?
От: RussianFellow Россия http://russianfellow.livejournal.com
Дата: 28.06.16 08:55
Оценка: -1 :)
Как преобразовать CString в char* или в char[] ?

У меня есть такой код:

CString myString;
char s[30];
int i, n;

//...

n = myString.GetLength();
LPTSTR pzsText = (LPTSTR)(myString.GetBuffer(n));
for (i=0; i<n; i++) s[i] = pszText[i];
s[n] = '\0';

У меня стоит поддержка Юникод, поэтому этот код правильно работает.

Но нельзя ли написать проще? И чтобы работало для всех случаев, а не только для поддержки Юникода?
1613 г. = 2024 г.
Re: Как преобразовать CString в char* (char[]) ?
От: Stanislav V. Zudin Россия  
Дата: 28.06.16 09:23
Оценка:
Здравствуйте, RussianFellow, Вы писали:

RF>Как преобразовать CString в char* или в char[] ?


Канонично использовать GetBuffer()/ReleaseBuffer()
Если требуется именно неконстантная строка.

RF>У меня есть такой код:


RF>CString myString;

RF>char s[30];
RF>int i, n;

RF>//...


RF>n = myString.GetLength();

RF>LPTSTR pzsText = (LPTSTR)(myString.GetBuffer(n));
RF>for (i=0; i<n; i++) s[i] = pszText[i];
RF>s[n] = '\0';


RF>Но нельзя ли написать проще? И чтобы работало для всех случаев, а не только для поддержки Юникода?


В данном случае логично написать
_tcscpy(s, myString.GetString());
_____________________
С уважением,
Stanislav V. Zudin
Re: Как преобразовать CString в char* (char[]) ?
От: peterbes Россия  
Дата: 28.06.16 12:44
Оценка:
Здравствуйте, RussianFellow, Вы писали:


RF>n = myString.GetLength();

RF>LPTSTR pzsText = (LPTSTR)(myString.GetBuffer(n));
RF>for (i=0; i<n; i++) s[i] = pszText[i];
RF>s[n] = '\0';

RF>У меня стоит поддержка Юникод, поэтому этот код правильно работает.


Запусти свой код и сам увидишь, что работает всё неправильно, во-первых, выведет не то, что ты ждешь, во-вторых, код сам по себе падучий.
В (ATL)MFC с большой осторожностью в однопоточных приложениях можно использовать связку макросов USES_CONVERSION и W2A, или же во всех других случаях использовать WideCharToMultiByte
Re: Как преобразовать CString в char* (char[]) ?
От: b0r3d0m  
Дата: 29.06.16 21:50
Оценка:
RF>Как преобразовать CString в char* или в char[] ?

Первый же результат по запросу "CString to char*" в Google ведёт на RSDN -- http://rsdn.ru/forum/mfc/206088.flat
Автор:
Дата: 03.03.03

Там же во втором сообщении есть ответ на ваш вопрос.

RF>У меня есть такой код:


RF>CString myString;

RF>char s[30];
RF>int i, n;

RF>//...


RF>n = myString.GetLength();

RF>LPTSTR pzsText = (LPTSTR)(myString.GetBuffer(n));
RF>for (i=0; i<n; i++) s[i] = pszText[i];
RF>s[n] = '\0';

Вообще какой-то треш, а не код, честно говоря.

По пунктам:

— Какие char s[30]?
— GetBuffer можно вызывать без аргумента, если требуется получить все символы
— Зачем это посимвольное копирование?

RF>У меня стоит поддержка Юникод, поэтому этот код правильно работает.


???

Может быть, MBCS?
Re[2]: Как преобразовать CString в char* (char[]) ?
От: b0r3d0m  
Дата: 29.06.16 21:51
Оценка:
SVZ>Канонично использовать GetBuffer()/ReleaseBuffer()

ReleaseBuffer вызывать необязательно, если никаких изменений над полученным буфером произведено не было.
Re[2]: Как преобразовать CString в char* (char[]) ?
От: b0r3d0m  
Дата: 29.06.16 21:51
Оценка:
SVZ>В данном случае логично написать
SVZ>_tcscpy(s, myString.GetString());

И вылезти за границы массива...
Re[2]: Как преобразовать CString в char* (char[]) ?
От: b0r3d0m  
Дата: 29.06.16 21:52
Оценка:
P>В (ATL)MFC с большой осторожностью в однопоточных приложениях можно использовать связку макросов USES_CONVERSION и W2A

А что с ними не так в многопоточных?
Re[3]: Как преобразовать CString в char* (char[]) ?
От: peterbes Россия  
Дата: 30.06.16 12:26
Оценка:
Здравствуйте, b0r3d0m, Вы писали:

P>>В (ATL)MFC с большой осторожностью в однопоточных приложениях можно использовать связку макросов USES_CONVERSION и W2A


B>А что с ними не так в многопоточных?


В недрах макроса для выделения памяти используется aloca, эта функция выделяет память не из общей кучи а на стеке. Проблема для aloca описана в https://msdn.microsoft.com/ru-ru/library/wb1s57t5.aspx

Я бы об этом и не знал, если бы сам не столкнулся
Re[4]: Как преобразовать CString в char* (char[]) ?
От: peterbes Россия  
Дата: 30.06.16 12:43
Оценка:
А в однопоточном программа упадет сразу, если сделать что-то подобное

for(i=0;i<0xFFFF;i++)
{
    CString Str;
    char* pStr;
    ....
    pStr = W2A(Str);
    ....
}
Re[5]: Как преобразовать CString в char* (char[]) ?
От: b0r3d0m  
Дата: 30.06.16 14:40
Оценка:
P>А в однопоточном программа упадет сразу, если сделать что-то подобное

P>
P>for(i=0;i<0xFFFF;i++)
P>{
P>    CString Str;
P>    char* pStr;
P>    ....
P>    pStr = W2A(Str);
P>    ....
P>}
P>


Ну, это-то понятно, оно даже в документации описано:

The allocated space is automatically freed when the calling function exits (not when the allocation merely passes out of scope)


А вот с многопоточным кодом я всё же не понял...

Почитал доки alloca, но никаких упоминаний о multithreading'е там не встретил. У каждой нити исполнения ведь свой стек, в чём тогда может быть проблема? Пускай себе юзают alloca в недрах.
Re[6]: Как преобразовать CString в char* (char[]) ?
От: b0r3d0m  
Дата: 30.06.16 17:41
Оценка:
B>А вот с многопоточным кодом я всё же не понял...

B>Почитал доки alloca, но никаких упоминаний о multithreading'е там не встретил. У каждой нити исполнения ведь свой стек, в чём тогда может быть проблема? Пускай себе юзают alloca в недрах.


А, или вы о том, что аллоцируемый alloc'ом буфер нельзя юзать из другого потока? Ну, оно, в принципе, логично -- стек у каждого свой, очистится он может в любой непредсказуемый для другого потока момент etc.
Re[7]: Как преобразовать CString в char* (char[]) ?
От: b0r3d0m  
Дата: 30.06.16 17:43
Оценка:
B>А, или вы о том, что аллоцируемый alloc'ом буфер нельзя юзать из другого потока? Ну, оно, в принципе, логично -- стек у каждого свой, очистится он может в любой непредсказуемый для другого потока момент etc.

Я-то уж было подумал, что вызовы alloca непотокобезопасны.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.