Лучший способ создать строковый буфер для двоичных данных - PullRequest
2 голосов
/ 12 декабря 2011

Когда я пытаюсь сделать следующее, я получаю сообщение об ошибке:

unsigned char * data = "00000000"; //error: cannot convert const char to unsigned char

Есть ли какой-то особый способ сделать это, которого мне не хватает?

Обновление

Ради краткости я объясню, чего я пытаюсь достичь:

Я хотел бы создать StringBuffer в C ++, который использует значения без знака для необработанных двоичных данных. Кажется, что неподписанный символ - лучший способ достигнуть этого. Если есть лучший метод?

Ответы [ 7 ]

2 голосов
/ 12 декабря 2011
std::vector<unsigned char> data(8, '0');

Или, если данные не однородны:

auto & arr = "abcdefg";
std::vector<unsigned char> data(arr, arr + sizeof(arr) - 1);

Или, так что вы можете назначить непосредственно из литерала:

std::basic_string<unsigned char> data = (const unsigned char *)"abcdefg";
2 голосов
/ 12 декабря 2011

У вас есть много способов. Нужно написать:

const unsigned char *data = (const unsigned char *)"00000000";

Другой, более рекомендуемый - объявить data так, как должно быть:

const char *data = "00000000";

А когда вы передадите его своей функции:

myFunc((const unsigned char *)data);

Обратите внимание, что обычно строка unsigned char является необычной. Массив беззнаковых символов более распространен, но вы не инициализируете его строкой («00000000»)

Ответ на ваше обновление

Если вам нужны необработанные двоичные данные, сначала позвольте мне сказать вам, что вместо unsigned char вам лучше использовать большие контейнеры, такие как long int или long long. Это потому, что когда вы выполняете операции над двоичным литералом (который является массивом), ваши операции сокращаются на 4 или 8, что является повышением скорости.

Во-вторых, если вы хотите, чтобы ваш класс представлял двоичные значения, инициализируйте его не строкой, а отдельными значениями. В вашем случае будет:

unsigned char data[] = {0x30, 0x30, 0x30, 0x30, /* etc */}

Обратите внимание , что я предполагаю, что вы храните двоичный файл как двоичный файл! То есть вы получаете 8 битов в беззнаковом символе Если вы, с другой стороны, имеете в виду двоичный файл, как в строке 0 и 1, что не очень хорошая идея, но в любом случае вам не нужно unsigned char и достаточно просто char.

2 голосов
/ 12 декабря 2011
unsigned char data[] = "00000000";

Это скопирует "00000000" в буфер unsigned char[], что также означает, что буфер не будет доступен только для чтения, как строковый литерал.

Причина, по которой ваш способ не работает, заключается в том, что ваш указывает data на (signed) строковый литерал (char[]), поэтому данные должны быть типа char*. Вы не можете сделать это без явного приведения "00000000", такого как: (unsigned char*)"00000000".

Обратите внимание, что строковые литералы явно не имеют типа constchar[], однако, если вы не обращаетесь с ними как таковыми и не пытаетесь их изменить, вы будете вызвать неопределенное поведение - в большинстве случаев это ошибка нарушения прав доступа.

2 голосов
/ 12 декабря 2011

Да, сделайте это:

const char *data = "00000000";

Строковый литерал - это массив char, а не unsigned char.

Если вам нужно передать это в функцию, которая принимает const unsigned char *, то вам нужно ее привести:

foo(static_cast<const unsigned char *>(data));
1 голос
/ 12 декабря 2011

Ваша целевая переменная является указателем на unsigned char. «00000000» - это строковый литерал. Это тип const char[9]. У вас есть два несоответствия типов здесь. Во-первых, unsigned char и char - это разные типы. Отсутствие квалификатора const также является большой проблемой.

Вы можете сделать это:

unsigned char * data = (unsigned char *)"00000000";

Но это то, что вы не должны делать. Когда-либо. Отказ от константности строкового литерала однажды доставит вам большие неприятности.

Следующее немного лучше, но, строго говоря, это все еще неопределенное поведение (возможно, неопределенное поведение; я не хочу преследовать, какое оно есть в стандарте):

const unsigned char * data = (const unsigned char *)"00000000";

Здесь вы сохраняете постоянство, но вы меняете тип указателя с char* на unsigned char*.

1 голос
/ 12 декабря 2011

Вы пытаетесь присвоить строковое значение указателю на беззнаковый символ. Тебе этого не сделать. Если у вас есть указатель, вы можете назначить ему только адрес памяти или NULL.

Вместо этого используйте const char.

0 голосов
/ 12 декабря 2011

@ Holland -

unsigned char * data = "00000000"; 

Один очень важный момент, я не уверен, что мы проясняем: строка «00000000 \ 0» (9 байт, включая разделитель) может быть доступна только для чтенияПАМЯТЬ (в зависимости от вашей платформы).

Другими словами, если вы определили свою переменную («данные») таким образом и передали ее функции, которая может пытаться ИЗМЕНИТЬ «данные» ... тогдаВы можете получить НАРУШЕНИЕ ДОСТУПА.

Решение:

1) объявить как "const char *" (как уже сказали другие)

  ... and ...

2) ОБРАЩАЙТЕ его как «const char *» (НЕ модифицируйте его содержимое и не передавайте его функции, которая может изменить его содержимое).

...