Лучший способ Создать Строковый буфер для двоичных данных


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

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

Есть ли какой-то особый способ сделать это, который я упускаю?

Обновить

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

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

7 2

7 ответов:

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";

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

const char *data = "00000000";
Строковый литерал-это массив char, а не unsigned char.

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

foo(static_cast<const unsigned char *>(data));

У вас есть много способов. Один из них должен написать:

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 бит в беззнаковом символе. Если вы, с другой стороны, имеете в виду двоичный код, как в строке 0s и 1s, что на самом деле не очень хорошая идея, но в любом случае, вам действительно не нужно unsigned char и достаточно просто char.

unsigned char data[] = "00000000";

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

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

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

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

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

Ваша целевая переменная является указателем на 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*.

@Holland -

unsigned char * data = "00000000"; 

Один очень важный момент, который я не уверен, что мы проясняем: строка "00000000\0" (9 байт, включая разделитель) может находиться в памяти только для чтения (в зависимости от вашей платформы).

Другими словами, если вы определили переменную ("данные") таким образом и передали ее функции, которая может попытаться изменить" данные"... тогда вы можете получить нарушение доступа.

Решение таково:

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

  ... and ...

2) рассматривайте его как "const char *" (не изменяйте его содержимое или не передавайте его функции, которая может изменить его содержимое).