Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Проблема с конвертацией строк на С++ (http://forum.oszone.net/showthread.php?t=45433)

Kelasant 15-02-2005 15:25 298533

Проблема с конвертацией строк на С++
 
Привет всем!

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

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 298536

Потому что ss - это указатель.

Kelasant 15-02-2005 15:40 298538

Тогда скажите, плиз, как мне сделать так, чтобы сей указатель указывал на правильное значение? Что нужно создать и как туда нужно переконвертить?

hasherfrog 15-02-2005 15:55 298542

ss - указатель. Его значение всегда в шестнадцатеричном виде будет давать не-пойми-что. Другое дело - содержимое памяти по этому адресу. А Вы так и не сказали, чем смотрите это самое содержимое (... памяти по адресу, который хранится в указателе ss). printf? wprintf? SetWindowText?
Посмотрите тут по поводу _типов_ указателей (и слева там в меню пощелкайте).
Для перевода _содержимого_ одних строк в другие: тут.

Kelasant 15-02-2005 16:05 298552

Спасибо

shurikan 18-02-2005 16:31 299651

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 299729

Да, спасибо, я понял :)

hasherfrog 18-02-2005 23:32 299754

А я ни фига не понял. в первый раз в жизни вижу такое:
Цитата:

нужно
Код:
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 299988

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

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

P.S. Мне тоже стало интересно насчет
Цитата:

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

hasherfrog 20-02-2005 02:33 300052

Нужно
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 300204

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

Kelasant 25-02-2005 00:04 301402

Черт возьми, не думал, что придется вернуться к этой теме.

Есть:

//структура:
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 301413

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

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

Kelasant 25-02-2005 16:19 301581

Вероятно, эмоции помешали более внятно изложить вопрос.

Значит так: есть такая структура (описанная в 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;
- один фиг, все пустое. В одной форме присваивается, в другой нет :(
Ощущаю себя полным профаном :(

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

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


Время: 07:08.

Время: 07:08.
© OSzone.net 2001-