Member 14039607 Ответов: 2

Как преобразовать шестнадцатеричный LPCTSTR в байт


У меня есть функция ниже


void StrToByte2(LPCTSTR str, BYTE *dest)
{
	UINT count = _ttoi(str);
	BYTE buf[4] = { 0 };
	char string[10] = { 0 };
	sprintf_s(string, 10, "%04d", count);
	for (int i = 0; i < 4; ++i)
	{
		if ((string[i] >= '0') && (string[i] <= '9'))
			buf[i] = string[i] - '0';
	}
	dest[0] = (BYTE)(buf[0] << 4) | buf[1];
	dest[1] = (BYTE)(buf[2] << 4) | buf[3];
}


Если я вызову эту функцию на "1234" ( любые цифры) , dest выведет около 12814!

struct st               
{
    byte    btID[2];
    int     nID;
};

PTR ptr(new st);
StrToByte2(strCode, ptr->btID);


но когда я вызываю эту функцию на любом шестнадцатеричном ex A123 , она всегда выводит 0000.

Приведенная ниже функция используется для обратного преобразования кода dest в str

CString Byte2ToStr(const byte* pbuf)
{
    CString str;
    str.Format(_T("%02X%02X"), pbuf[0], pbuf[1]);
    return str;
}


Как я могу получить A123 для преобразования в байты, а затем обратно в str для отображения A123??

Пожалуйста, помогите!!

Что я уже пробовал:

Попробовал ниже функцию ,но на convert back to str, некоторые я не вижу A123, но insted какое-то случайное число, например 1348

void StrToByte2(LPCTSTR str, BYTE *dest)
{
	BYTE buf[4] = { 0 };
	char string[10] = { 0 };
	sprintf_s(string, 10, "%04d", str);
	for (int i = 0; i < 4; ++i)
	{
		if ((string[i] >= '0') && (string[i] <= 'F'))
			buf[i] = string[i] - '0';
	}
	dest[0] = (BYTE)(buf[0] << 4) | buf[1];
	dest[1] = (BYTE)(buf[2] << 4) | buf[3];
}

KarstenK

Решение 1 является правильным. Поскольку эти преобразования являются общими задачами, доступно множество функций. Используйте их, потому что они являются проверенным и проверенным кодом и безопасны даже в крайних случаях. ;-)

Rick York

Если ваши числа имеют типизирующие префиксы, такие как 0x для шестнадцатеричного и 0 для восьмеричного, то strtoul и _tcstoul могут справиться с ними. На самом деле, он принимает базу в качестве аргумента, так что вы можете дать ему двоичную или любую другую базу, которую вы хотите.

2 Ответов

Рейтинг:
2

TheGreatAndPowerfulOz

#include <cstdlib>

int main()
{
    char * p = NULL;
    long n = strtol( "abcd", & p, 16 );
    printf("%ld\r\n", n);
}


Рейтинг:
13

CPallini

Как было предложено, используйте (общий текстовый вариант) strtol:

void StrToByte2(LPCTSTR str, BYTE * dest)
{
	LONG u16 = _tcstol( str, NULL, 16);
	dest[0] = (BYTE) (u16 >> 8);
	dest[1] = (BYTE) (u16);
}



или, по крайней мере, написать разумную рукопись.

void StrToByte2Alt(LPCTSTR str, BYTE dest[])
{
	for (size_t b=0; b<2; ++b)
	{
		dest[b] = 0;
		for (size_t nb=0; nb<2; nb++)
		{
			dest[b] <<= 4;
			TCHAR tc = str[2*b+nb];
			if ( tc >= _T('0') && tc <= _T('9') )
				dest[b] |= tc - _T('0');
			else if ( tc >= _T('A') && tc <= _T('F') )
				dest[b] |= tc - _T('A') + 10;
			else if ( tc >= _T('a') && tc <= _T('f') )
				dest[b] |= tc - _T('a') + 10;
			else
			{// throw all the throwable here...
			}
		}
	}
}


или, используя C++ потоки:
#ifdef UNICODE
    typedef std::wistringstream InputStringStream;
#else
    typedef std::istringstream InputStringStream; 
#endif // UNICODE

BOOL strtobyte2(LPCTSTR str, std::array<BYTE, 2> & b)
{
	UINT16 u16;
	InputStringStream iss(str);
	iss >> hex >> u16;
	if ( ! iss) return FALSE; 
	b[0] = static_cast<BYTE>(u16 >> 8);
	b[1] = static_cast<BYTE>(u16);
	return TRUE;
}