Большой Воронежский Форум

Если это ваш первый визит, рекомендуем почитать справку по форуму. Для размещения своих сообщений необходимо зарегистрироваться. Для просмотра сообщений выберите раздел.
Вернуться   Большой Воронежский Форум » Компьютеры и все, что с ними связано » » Программирование
Философия, технологии, алгоритмы!

Ответ
 
Опции темы
Старый 08.02.2012, 17:04   #1   
///
 
Аватар для -=Женек=-
 
Сообщений: 9,724
Регистрация: 02.04.2005
Возраст: 43

-=Женек=- вне форума Не в сети
Как преобразовать данные из TStringList в unsigned char?

Господа, пишу в билдере.
Есть массив строк:
TStringList *Dat = new TStringList;
Dat->LoadFromFile("d:/hex.hex");//загрузка файла

Есть функция отправки байта SendUART(unsigned char command)

нужно чем-то обрастить строку SendUART(Dat->Strings[i].SubString(4,2)); чтобы передать 1 байт, HEX отображение которого и составляют два символа строки.

НАпример Dat->Strings[i].SubString(4,2) = "23" (что означает 0x23), а подставить в SendUART надо "#" или 35, то есть unsigned char.

Подскажите как.
  Ответить с цитированием
Старый 08.02.2012, 17:54   #2   
Форумец
 
Аватар для Spectator
 
Сообщений: 39,877
Регистрация: 27.05.2003
Возраст: 46

Spectator вне форума Не в сети
#include <stdlib.h>
long int strtol(const char *start, char **end, int radix);

start - это строка, в end будет хранится первый адрес первого символа после сконвертированного значения, в radix передай 16

На выходе будет нужный байт.

Так как функция будет пытаться преобразовать по максимуму, нужно будет каждые два символа записывать в отдельную строковую переменную.

А вообще быстрее и проще это сделать вручную, через switch:

long CharToIntVal(char a)
{
switch (a) {
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;

case 'A': return 10;
case 'B': return 11;
case 'C': return 12;
case 'D': return 13;
case 'E': return 14;
case 'F': return 15;

case 'a': return 10;
case 'b': return 11;
case 'c': return 12;
case 'd': return 13;
case 'e': return 14;
case 'f': return 15;

default: return -1;
}
}

CharToIntVal(arr[0]*16) + CharToIntVal(arr[1])
CharToIntVal(arr[2]*16) + CharToIntVal(arr[3])

и т.д.
  Ответить с цитированием
Старый 08.02.2012, 19:15   #3   
бибизьян
 
Аватар для aerin
 
Сообщений: 3,031
Регистрация: 17.02.2004

aerin вне форума Не в сети
Spectator, а зачем код символа перед передачей в функцию умножать на 16?
  Ответить с цитированием
Старый 08.02.2012, 19:18   #4   
Форумец
 
Аватар для Spectator
 
Сообщений: 39,877
Регистрация: 27.05.2003
Возраст: 46

Spectator вне форума Не в сети
Цитата:
Сообщение от aerin Посмотреть сообщение
Spectator, а зачем код символа перед передачей в функцию умножать на 16?
Ошибся
не
CharToIntVal(arr[0]*16) + CharToIntVal(arr[1])
а
CharToIntVal(arr[0])*16 + CharToIntVal(arr[1])
тогда из строки 'A5' мы получим числовое значение.
  Ответить с цитированием
Старый 08.02.2012, 19:27   #5   
бибизьян
 
Аватар для aerin
 
Сообщений: 3,031
Регистрация: 17.02.2004

aerin вне форума Не в сети
А так не проще:
Цитата:
sscanf( строка_где_это_лежит, "%2x", &переменная_куда_покласть );
?
  Ответить с цитированием
Старый 08.02.2012, 19:34   #6   
Форумец
 
Аватар для Spectator
 
Сообщений: 39,877
Регистрация: 27.05.2003
Возраст: 46

Spectator вне форума Не в сети
Цитата:
Сообщение от aerin Посмотреть сообщение
А так не проще:
?
Тогда уж лучше то что я говорил выше:
int n = strtol("A5", NULL, 16);//n=165
  Ответить с цитированием
Старый 08.02.2012, 20:16   #7   
///
 
Аватар для -=Женек=-
 
Сообщений: 9,724
Регистрация: 02.04.2005
Возраст: 43

-=Женек=- вне форума Не в сети
Цитата:
Сообщение от Spectator Посмотреть сообщение
Тогда уж лучше то что я говорил выше:
int n = strtol("A5", NULL, 16);//n=165
Спасибо, помогло.
Но помогите заставить работать это:

Цитата:
TStringList *Dat = new TStringList;
Dat->LoadFromFile("d:/hex.hex");//загрузка файла

unsigned char n = strtol( Dat->Strings[1].SubString(2,2).c_str() , NULL, 16);//n=165
Выдает ошибки:
BCC32 Error] SMD_Reflow.cpp(1167): E2034 Cannot convert 'wchar_t *' to 'const char *'
[BCC32 Error] SMD_Reflow.cpp(1167): E2342 Type mismatch in parameter '__s' (wanted 'const char *', got 'wchar_t *')

Последний раз редактировалось -=Женек=-; 08.02.2012 в 20:33.
  Ответить с цитированием
Старый 08.02.2012, 21:07   #8   
///
 
Аватар для -=Женек=-
 
Сообщений: 9,724
Регистрация: 02.04.2005
Возраст: 43

-=Женек=- вне форума Не в сети
Вот оно че:
unsigned char n = wcstol( Dat->Strings[0].SubString(2,2).c_str() , NULL, 16);
  Ответить с цитированием
Старый 08.02.2012, 21:45   #9   
бибизьян
 
Аватар для aerin
 
Сообщений: 3,031
Регистрация: 17.02.2004

aerin вне форума Не в сети
Цитата:
Сообщение от Spectator
Тогда уж лучше то что я говорил выше:
int n = strtol("A5", NULL, 16);//n=165
Нет, не лучше. В исходной задаче ничего не говорится о символах, идущих за этими двумя, поэтому:
int n = strtol("A5", NULL, 16);//n=165,
а n = strtol("A5B6", NULL, 16);//n=42422
с другой стороны:
sscanf( "A5", "%2x", &n ); // n = 165
и
sscanf( "A5B6", "%2x", &n ); // n = 165
  Ответить с цитированием
Старый 08.02.2012, 21:55   #10   
Форумец
 
Аватар для Spectator
 
Сообщений: 39,877
Регистрация: 27.05.2003
Возраст: 46

Spectator вне форума Не в сети
Цитата:
Сообщение от aerin Посмотреть сообщение
Нет, не лучше. В исходной задаче ничего не говорится о символах, идущих за этими двумя, поэтому:
int n = strtol("A5", NULL, 16);//n=165,
а n = strtol("A5B6", NULL, 16);//n=42422
Что смешного, в калькуляторе проверь виндовом, все верно)

Цитата:
Сообщение от aerin Посмотреть сообщение
с другой стороны:
sscanf( "A5", "%2x", &n ); // n = 165
и
sscanf( "A5B6", "%2x", &n ); // n = 165
char sz[]="A5B6";
char c = sz[2];
sz[2] = 0;
int n = strtol(sz, NULL, 16);//n=165,
sz[2] = c;
Так просто наверняка будет быстрее.
  Ответить с цитированием
Старый 08.02.2012, 22:05   #11   
Форумец
 
Аватар для Spectator
 
Сообщений: 39,877
Регистрация: 27.05.2003
Возраст: 46

Spectator вне форума Не в сети
Цитата:
Сообщение от -=Женек=- Посмотреть сообщение
Вот оно че:
unsigned char n = wcstol( Dat->Strings[0].SubString(2,2).c_str() , NULL, 16);
Это от версии и настроек билдера зависит, у меня тот пример, который у тебя выдавал ошибки, откомпилировался без вопросов.
  Ответить с цитированием
Старый 08.02.2012, 22:48   #12   
бибизьян
 
Аватар для aerin
 
Сообщений: 3,031
Регистрация: 17.02.2004

aerin вне форума Не в сети
Цитата:
Сообщение от Spectator
Что смешного, в калькуляторе проверь виндовом, все верно)
Смешно то, что код неработоспособный.
Цитата:
Сообщение от Spectator
char sz[]="A5B6";
char c = sz[2];
sz[2] = 0;
int n = strtol(sz, NULL, 16);//n=165,
sz[2] = c;
Так просто наверняка будет быстрее.
Не уверен, что TStringList благосклонно отнесется к такому надругательству над своими членами.
Цитата:
Это от версии и настроек билдера зависит, у меня тот пример, который у тебя выдавал ошибки, откомпилировался без вопросов.
Это зависит от того, UNICODE-ная версия рантайма используется для сборки или нет.
  Ответить с цитированием
Старый 08.02.2012, 22:59   #13   
Форумец
 
Аватар для Spectator
 
Сообщений: 39,877
Регистрация: 27.05.2003
Возраст: 46

Spectator вне форума Не в сети
Цитата:
Сообщение от aerin Посмотреть сообщение
Смешно то, что код неработоспособный.

Не уверен, что TStringList благосклонно отнесется к такому надругательству над своими членами.
Безусловно, поскольку он вернет константную строку, ее надо будет предварительно скопировать в локальный массив char'ов, т.е. строку.

Цитата:
Сообщение от aerin Посмотреть сообщение
Это зависит от того, UNICODE-ная версия рантайма используется для сборки или нет.
Рантайм там один, всё зависит от опций компилятора. Какая функция используется по умолчанию.
Есть вот замечательная функция CreateWindow, которая создает окно. Фокус состоит в том что ее на самом деле давно уже нет. Есть CreateWindowA и CreateWindowW и, в зависимости от настроек и / или define'ов подставляется либо та либо другая, когда пишешь CreateWindow.
Здесь примерно такая же бодяга.
  Ответить с цитированием
Старый 08.02.2012, 23:25   #14   
бибизьян
 
Аватар для aerin
 
Сообщений: 3,031
Регистрация: 17.02.2004

aerin вне форума Не в сети
Цитата:
Сообщение от Spectator
Безусловно, поскольку он вернет константную строку, ее надо будет предварительно скопировать в локальный массив char'ов, т.е. строку.
В моем понимании "надо будет предварительно скопировать в локальный массив char'ов" и "так просто наверняка будет быстрее" сочетаются слабо.
Цитата:
Сообщение от Spectator
Рантайм там один, всё зависит от опций компилятора. Какая функция используется по умолчанию.
Есть вот замечательная функция CreateWindow, которая создает окно. Фокус состоит в том что ее на самом деле давно уже нет. Есть CreateWindowA и CreateWindowW и, в зависимости от настроек и / или define'ов подставляется либо та либо другая, когда пишешь CreateWindow.
Здесь примерно такая же бодяга.
Сколько там рантаймов, я не знаю, т.к. не работаю с этим компайлером. Подозреваю, что под "опциями компилятора" вы понимаете наличие или отсутствие определения UNICODE.
И далее, я открою вам страшную военную тайну: CreateWindow никогда не была функцией, да и функций CreateWindowA и CreateWindowW тоже давно уже нет:
Цитата:
Сообщение от WinUser.h
#define CreateWindowA(lpClassName, lpWindowName, dwStyle, x, y,\
nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)\
CreateWindowExA(0L, lpClassName, lpWindowName, dwStyle, x, y,\
nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)
#define CreateWindowW(lpClassName, lpWindowName, dwStyle, x, y,\
nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)\
CreateWindowExW(0L, lpClassName, lpWindowName, dwStyle, x, y,\
nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)
#ifdef UNICODE
#define CreateWindow CreateWindowW
#else
#define CreateWindow CreateWindowA
#endif // !UNICODE
  Ответить с цитированием
Старый 08.02.2012, 23:26   #15   
бибизьян
 
Аватар для aerin
 
Сообщений: 3,031
Регистрация: 17.02.2004

aerin вне форума Не в сети
Spectator, да, забыл сказать, только вы никому! Тс-с-с-с!
  Ответить с цитированием
Старый 08.02.2012, 23:44   #16   
Форумец
 
Аватар для Spectator
 
Сообщений: 39,877
Регистрация: 27.05.2003
Возраст: 46

Spectator вне форума Не в сети
Цитата:
Сообщение от aerin Посмотреть сообщение
В моем понимании "надо будет предварительно скопировать в локальный массив char'ов" и "так просто наверняка будет быстрее" сочетаются слабо.
Копирование будет выполнено ГОРАЗДО быстрее, чем вызов sprintf, фактически - это одна ассемблерная операция. А sprintf - та еще махина, которая совсем для других целей предназначена. Не возьмусь гарантировать, но разница раз в 100 по скорости выполнения вполне предсказуема.

Цитата:
Сообщение от aerin Посмотреть сообщение
Сколько там рантаймов, я не знаю, т.к. не работаю с этим компайлером. Подозреваю, что под "опциями компилятора" вы понимаете наличие или отсутствие определения UNICODE.
И далее, я открою вам страшную военную тайну: CreateWindow никогда не была функцией, да и функций CreateWindowA и CreateWindowW тоже давно уже нет:
Была Разделение на CreateWindowA и CreateWindowW произошло даже не в 95 винде, а только в XP.
То что в ультрасовременных ОС подменили и вызов CreateWindow* на вызов CreateWindowEx* - вполне верю. В XP лично с отладчиком их (CreateWindow*) наблюдал в ядре.
  Ответить с цитированием
Старый 09.02.2012, 04:04   #17   
Форумец
 
Аватар для pwei
 
Сообщений: 172
Регистрация: 04.05.2008
Возраст: 39

pwei вне форума Не в сети
что-то слишком часто слышу в это разделе звук сливного бачка
  Ответить с цитированием
Старый 09.02.2012, 07:36   #18   
Registered User
 
Сообщений: 1,114
Регистрация: 23.06.2007
Возраст: 56

Hopkroft вне форума Не в сети
Цитата:
Сообщение от Spectator Посмотреть сообщение
Была Разделение на CreateWindowA и CreateWindowW произошло даже не в 95 винде, а только в XP.
А разве этого не было в Windows 2000?
  Ответить с цитированием
Старый 09.02.2012, 11:34   #19   
Форумец
 
Аватар для Spectator
 
Сообщений: 39,877
Регистрация: 27.05.2003
Возраст: 46

Spectator вне форума Не в сети
Цитата:
Сообщение от Hopkroft Посмотреть сообщение
А разве этого не было в Windows 2000?
Может быть и в 2000, она как то мимо меня прошла, я с 95 сразу на XP перешел.
  Ответить с цитированием
Старый 09.02.2012, 11:41   #20   
бибизьян
 
Аватар для aerin
 
Сообщений: 3,031
Регистрация: 17.02.2004

aerin вне форума Не в сети
Цитата:
Сообщение от Spectator
Копирование будет выполнено ГОРАЗДО быстрее, чем вызов sprintf, фактически - это одна ассемблерная операция. А sprintf - та еще махина, которая совсем для других целей предназначена. Не возьмусь гарантировать, но разница раз в 100 по скорости выполнения вполне предсказуема.
Жаль пацаны из intel-а не знают про эту волшебную инструкцию и делают все по-старинке:
Цитата:
;char *strcpy(dst, src) - copy one string over another
;
;Purpose:
; Copies the string src into the spot specified by
; dest; assumes enough room.
;
; Algorithm:
; char * strcpy (char * dst, char * src)
; {
; char * cp = dst;
;
; while( *cp++ = *src++ )
; ; /* Copy src over dst */
; return( dst );
; }
;
;Entry:
; char * dst - string over which "src" is to be copied
; const char * src - string to be copied over "dst"
;
;Exit:
; The address of "dst" in EAX
;
;Uses:
; EAX, ECX
;
;Exceptions:
;************************************************* ******************************
CODESEG

% public strcpy
strcpy proc \
dsttr byte, \
srctr byte

OPTION PROLOGUE:NONE, EPILOGUE:NONE

push edi ; preserve edi
mov edi,[esp+8] ; edi points to dest string
jmp short copy_start

strcpy endp

align 16


; edi points to the end of dest string.
copy_start::
mov ecx,[esp+0ch] ; ecx -> sorc string
test ecx,3 ; test if string is aligned on 32 bits
je short main_loop_entrance

main_loop: ; edx contains first dword of sorc string
mov [edi],edx ; store one more dword
add edi,4 ; kick dest pointer
main_loop_entrance:
mov edx,7efefeffh
mov eax,dword ptr [ecx] ; read 4 bytes

add edx,eax
xor eax,-1

xor eax,edx
mov edx,[ecx] ; it's in cache now

add ecx,4 ; kick dest pointer
test eax,81010100h

je short main_loop
; found zero byte in the loop
; main_loop_end:
test dl,dl ; is it byte 0
je short byte_0
test dh,dh ; is it byte 1
je short byte_1
test edx,00ff0000h ; is it byte 2
je short byte_2
test edx,0ff000000h ; is it byte 3
je short byte_3
jmp short main_loop ; taken if bits 24-30 are clear and bit
; 31 is set
byte_3:
mov [edi],edx
mov eax,[esp+8] ; return in eax pointer to dest string
pop edi
ret
byte_2:
mov [edi],dx
mov eax,[esp+8] ; return in eax pointer to dest string
mov byte ptr [edi+2],0
pop edi
ret
byte_1:
mov [edi],dx
mov eax,[esp+8] ; return in eax pointer to dest string
pop edi
ret
byte_0:
mov [edi],dl
mov eax,[esp+8] ; return in eax pointer to dest string
pop edi
ret
или может мы будем копировать через memcpy:
Цитата:
void * __cdecl memcpy (
void * dst,
const void * src,
size_t count
)
{
void * ret = dst;

#if defined (_M_IA64)

{


__declspec(dllimport)


void RtlCopyMemory( void *, const void *, size_t count );

RtlCopyMemory( dst, src, count );

}

#else /* defined (_M_IA64) */
/*
* copy from lower addresses to higher addresses
*/
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
#endif /* defined (_M_IA64) */

return(ret);
}
тоже засада... Так где ж она та волшебная "ассемблерная операция"?

Цитата:
Сообщение от Spectator
Была Разделение на CreateWindowA и CreateWindowW произошло даже не в 95 винде, а только в XP.
То что в ультрасовременных ОС подменили и вызов CreateWindow* на вызов CreateWindowEx* - вполне верю. В XP лично с отладчиком их (CreateWindow*) наблюдал в ядре.
Я не знаю, что ты там наблюдал в ядре, но CreateWindowEx была еще до выхода win32s, т.е. в 16-разрядной винде, и смысла использования CreateWindow не было уже в 1992 году. В nt3.5 CreateWindow, подозреваю как и в win95, была просто стабом, которая передавала параметры в CreateWindowEx. На эту тему была очень хорошая статья в technet, правда вышла она уже во времена nt4. Первые функции с постфиксами W появились в win95, а возможно и в win32s, проверять лениво.
Одно непонятно, каким боком это все относится к вопросу ТС:
Цитата:
Выдает ошибки:
BCC32 Error] SMD_Reflow.cpp(1167): E2034 Cannot convert 'wchar_t *' to 'const char *'
[BCC32 Error] SMD_Reflow.cpp(1167): E2342 Type mismatch in parameter '__s' (wanted 'const char *', got 'wchar_t *')
или strtol уже перебралась из рантайма в ядро?

Последний раз редактировалось aerin; 09.02.2012 в 14:59.
  Ответить с цитированием
Поиск в теме: 



Быстрый переход:

  Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Support by DrIQ & Netwind