Показать полную графическую версию : Проблема с конвертацией строк на С++
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
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.