Войти

Показать полную графическую версию : Проблема с конвертацией строк на С++


Kelasant
15-02-2005, 15:25
Привет всем!

Есть такой блок:

char* ts = new char[100];
memset(ts, 0, sizeof(ts));
StrPCopy(ts, edMyText->Text);
// здесь ts имеет правильное значение "T-XP1"
LPWSTR ss = (LPWSTR)ts;
// здесь ss имеет значение "\x2D54\x50581"

Обьясните, плиз, в чем дело?
Почему ss не равно "T-XP1"?

hasherfrog
15-02-2005, 15:34
Потому что ss - это указатель.

Kelasant
15-02-2005, 15:40
Тогда скажите, плиз, как мне сделать так, чтобы сей указатель указывал на правильное значение? Что нужно создать и как туда нужно переконвертить?

hasherfrog
15-02-2005, 15:55
ss - указатель. Его значение всегда в шестнадцатеричном виде будет давать не-пойми-что. Другое дело - содержимое памяти по этому адресу. А Вы так и не сказали, чем смотрите это самое содержимое (... памяти по адресу, который хранится в указателе ss). printf? wprintf? SetWindowText?
Посмотрите тут (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/unicode_90hf.asp) по поводу _типов_ указателей (и слева там в меню пощелкайте).
Для перевода _содержимого_ одних строк в другие: тут (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/unicode_4gxf.asp).

Kelasant
15-02-2005, 16:05
Спасибо

shurikan
18-02-2005, 16:31
Kelasant
// здесь ss имеет значение "\x2D54\x50581"
LPWSTR - это строка "широких" символов (Wide char STR). А поскольку начертаний "широких" символов с такими кодами в системе нет, строка выводится в шестнадцатеричных СЛОВАХ. \x2D54 - эквивалентна "обычной" строке "T-", т.к. '\x54' есть символ 'T', а '\x2D' -- соответственно '-'. Второе слово даст тебе "XP". Ну а 1 в конце от того, что размер "широкого" символа равен 2 байтам, а в строке остался один байт, естественно код отобразился как обычный символ. А произошло это из-за неправильного приведения. Строка скопировалась посимвольно без преобразования "обычных" символов в "широкие". Вместо
LPWSTR ss = (LPWSTR)ts;
нужно
LPWSTR ss = LPWSTR (ts);
и произойдет не приведения, а преобразование типа.
:)

Kelasant
18-02-2005, 21:27
Да, спасибо, я понял :)

hasherfrog
18-02-2005, 23:32
А я ни фига не понял. в первый раз в жизни вижу такое:
нужно
Код:
LPWSTR ss = LPWSTR (ts);

shurikan, Вы где такое взяли? Можно и мне почитать?

LPWSTR - тип данных - указатель. Pointer to a null-terminated string of 16-bit Unicode characters.
Хотя речь идёт о С++ (сабж), "явное преобразование типа" LPSTR в LPWSTR даст банальное "приведение типа" LPSTR к LPWSTR, никакой разницы. Содержимое памяти не превратится от этого некоим волшебным образом из CHAR в WCHAR.


PS. Кстати, тут ошибка:
char* ts = new char[100];
memset(ts, 0, sizeof(ts));

Kelasant
19-02-2005, 21:06
Я еще 15-го числа понял свои ошибки при конвертации. Дальше обьяснять не надо, спасибо - уже все работало в тот же день :)

hasherfrog, а где тут ошибка? Может, я не к месту использую sizeof ?

P.S. Мне тоже стало интересно насчет LPWSTR ss = LPWSTR (ts);. Но, будучи не очень силен в С++, я лишь поблагодарил за помощь ;)

hasherfrog
20-02-2005, 02:33
Нужно
memset(ts, 0, sizeof(char)*100);
Ну если короче, то
memset(ts, 0, 100);

А у Вас
memset(ts, 0, sizeof(ts));
даст
memset(ts, 0, sizeof(char*));
т.е.
memset(ts, 0, 4);

Kelasant
20-02-2005, 17:19
Спасибо.
Кстати, hasherfrog, подскажите: использование функции memset является хорошим способом инициализации пустых строк при создании и повторном использовании? Или принято это делать как-то иначе?

Kelasant
25-02-2005, 00:04
Черт возьми, не думал, что придется вернуться к этой теме.

Есть:

//структура:
struct PS {
...
String str;
...
};

//переменная ее типа
PS cs;

//и текст
char* ArcFile = new char[200];
memset(ArcFile, 0, sizeof(char)*200);
StrPCopy(ArcFile, cs.str);

хоть убейте, но не пойму, почему ArcFile остается пустым :(((
подставляю любую другую переменную типа AnsiString - на ура идет.
менял еще всяко этот код - ничего не понимаю.

ногами не бейте, а лучше подскажите, плиз.

hasherfrog
25-02-2005, 01:44
>> подставляю любую другую переменную типа AnsiString
Куда? куда подставляете? Что "всё" при этом идёт?
Kelasant, вы не торопитесь, давайте не спеша, поподробнее.
Вы перечитайте свой пост - сами смогли бы понять вопрос?

ПС. И кстати, вы как-то странно всё-таки работаете со строками... Мммм, "небезопасно", я бы так сказал. Откуда Вы, например, знаете, что длина cs.str меньше 200 байт? Ну это мелочи, конечно, но как-то не есть хорошо.

Kelasant
25-02-2005, 16:19
Вероятно, эмоции помешали более внятно изложить вопрос.

Значит так: есть такая структура (описанная в Types.h) и переменная ее типа (в Variables.h).


Например, в Settings.cpp
#include "Settings.h"
#include "Variables.h"

использование
edPath->Text = cs.str;
и
cs.str = edPath->Text;
работает отлично.


В определенный момент времени я хочу прочитать значение из поля структуры и преобразовать в null-terminated строку.
Это будет делаться в IForm.cpp:

#include "IForm.h"
#include "Variables.h"

...

char* ArcFile = new char[200];
memset(ArcFile, 0, sizeof(char)*200);
StrPCopy(ArcFile, cs.str);

В cs.str лежит красивая правильная строчка - видно дебагером (это все на Builder C++).
После StrPCopy переменная ArcCopy по прежнему указывает на область, заполенную нулями.

Но случайно пробовал сделать промежуточное присвоение - даже не присваивается!
Вариант 1: String tmp = cs.str;
Вариант 2: edMyTEdit->Text = cs.str;
- один фиг, все пустое. В одной форме присваивается, в другой нет :(
Ощущаю себя полным профаном :(

Может, есть какие-то особенности обращения со структурами?

З.Ы. замечание принимаю.
Конечно же, надо проверять длину строки, как и многое другое.




© OSzone.net 2001-2012