#c #type-conversion
#c #преобразование типа
Вопрос:
сегодня я попытался преобразовать шестнадцатеричную строку в символ без знака []
string test = "fe5f0c";
unsigned char* uchar= (unsigned char *)test.c_str();
cout << uchar << endl;
Это привело к выводу
fe5f0c
hrmpf :-(. Желаемое поведение было бы следующим:
unsigned char caTest[2];
caTest[0] = (unsigned char)0xfe;
caTest[1] = (unsigned char)0x5f;
caTest[2] = (unsigned char)0x0c;
cout << caTest << endl;
который печатает нечитаемый ascii-код. Как часто я делаю что-то не так ^^. Был бы признателен за любые предложения.
Заранее спасибо
Комментарии:
1. Ваш массив слишком мал, вы не можете назначить элементу 2 массив размером 2.
2. Кроме того, какой результат вы ожидаете при печати массива символов? Вы получите символы с кодами ASCII (или любой другой системы, используемой вашим компьютером) 254, 95, 12 и так далее. Какой результат вы на самом деле хотите? Это не ясно из вашего вопроса.
3. Я думаю, вы имели в виду,
unsigned char caTest[4];
и забылиcaTest[3] = 0;
, но все еще не ясно, чего вы хотите. Похоже , что вы хотите отправить ASCII-представления значений шестнадцатеричной пары в стандартный вывод, независимо от того, доступны ли они для печати.4. Хм, изначально я имел в виду caTest[3]; но если бы вы могли указать, зачем мне нужен caTest [3] = 0, я также был бы доволен caTest [4]. Что касается моего намерения, я попытался сделать то, что Пабло описал в своем ответе. Спасибо, что помогли мне.
5. @ftiaronsem: Вы обрабатываете
caTest
как строку. Строки заканчиваются нулем. Если вы этого не сделаете, то в конечном итоге вы будете читать дальше конца буфера.
Ответ №1:
Конечно, вам просто нужно изолировать интересующие вас биты после синтаксического анализа:
#include <string>
#include <cstdlib>
#include <iostream>
typedef unsigned char byte;
int main()
{
std::string test = "40414243";
unsigned long x = strtoul(test.c_str(), 0, 16);
byte a[] = {byte(x >> 24), byte(x >> 16), byte(x >> 8), byte(x), 0};
std::cout << a << std::endl;
}
Обратите внимание, что я изменил входную строку на восьмизначное число, поскольку в противном случае массив начинался бы со значения 0 и operator<<
интерпретировал бы это как конец, и вы бы ничего не смогли увидеть.
Комментарии:
1. Большое вам спасибо за ваш ответ, к сожалению, это не то, что я хотел сделать, мой план состоял в том, чтобы сделать то, что Пабло описал в своем посте. У вас есть какие-нибудь предложения о том, как я мог бы это реализовать. Я был бы очень признателен за вашу помощь.
2. @fti: Я обновил свой пост. Дает ли это ожидаемые результаты?
3. вау, это здорово, идеально. Поскольку строка довольно длинная, мне придется разделить ее и запустить цикл for над кодом, который вы мне дали. Но я могу с этим справиться (по крайней мере, я на это надеюсь ;-)). Спасибо за вашу помощь.
4. @fti: В таком случае, вероятно, проще обрабатывать только один байт за раз внутри цикла for.
Ответ №2:
"fe5f0c"
представляет собой строку из 6 байт (7 из которых содержат нулевой ограничитель). Если бы вы посмотрели на это как на массив, вы бы увидели:
char str[] = { 102, 101, 53, 102, 48, 99 };
Но вы хотите
unsigned char str[] = { 0xfe, 0x5f, 0x0c };
Первое является «удобочитаемым» представлением, тогда как второе — «машиночитаемыми» числами. Если вы хотите преобразовать между ними, вам нужно сделать это явно, используя код, аналогичный тому, что написал @Fred.
Приведение (в большинстве случаев) не подразумевает преобразования, вы просто говорите компилятору доверять вам и что он может забыть то, что, по его мнению, он знает о выражении, которое вы приводите.
Комментарии:
1. спасибо, это именно то, что я хочу. У вас есть какие-нибудь подсказки по коду, как должно выглядеть это преобразование? Это было бы действительно здорово.
Ответ №3:
Вот более простой способ для шестнадцатеричных строковых литералов:
unsigned char *uchar = "xfex5fx0c";