2

When I try the following, I get an error:

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

Is there a special way to do this which I'm missing?

Update

For the sake of brevity, I'll explain what I'm trying to achieve:

I'd like to create a StringBuffer in C++ which uses unsigned values for raw binary data. It seems that an unsigned char is the best way to accomplish this. If there is a better method?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
zeboidlund
  • 9,731
  • 31
  • 118
  • 180

7 Answers7

2

Yes, do this:

const char *data = "00000000";

A string literal is an array of char, not unsigned char.

If you need to pass this to a function that takes const unsigned char *, well, you'll need to cast it:

foo(static_cast<const unsigned char *>(data));
Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
2
unsigned char data[] = "00000000";

This will copy "00000000" into an unsigned char[] buffer, which also means that the buffer won't be read-only like a string literal.

The reason why the way you're doing it won't work is because your pointing data to a (signed) string literal (char[]), so data has to be of type char*. You can't do that without explicitly casting "00000000", such as: (unsigned char*)"00000000".

Note that string literals aren't explicitly of type constchar[], however if you don't treat them as such and try and modify them, you will cause undefined behaviour - a lot of the times being an access violation error.

AusCBloke
  • 18,014
  • 6
  • 40
  • 44
2

You have many ways. One is to write:

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

Another, which is more recommended is to declare data as it should be:

const char *data = "00000000";

And when you pass it to your function:

myFunc((const unsigned char *)data);

Note that, in general a string of unsigned char is unusual. An array of unsigned chars is more common, but you wouldn't initialize it with a string ("00000000")

Response to your update

If you want raw binary data, first let me tell you that instead of unsigned char, you are better off using bigger containers, such as long int or long long. This is because when you perform operations on the binary literal (which is an array), your operations are cut by 4 or 8, which is a speed boost.

Second, if you want your class to represent binary values, don't initialize it with a string, but with individual values. In your case would be:

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

Note that I assume you are storing binary as binary! That is, you get 8 bits in an unsigned char. If you, on the other hand, mean binary as in string of 0s and 1s, which is not really a good idea, but either way, you don't really need unsigned char and just char is sufficient.

Shahbaz
  • 46,337
  • 19
  • 116
  • 182
2
std::vector<unsigned char> data(8, '0');

Or, if the data is not uniform:

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

Or, so you can assign directly from a literal:

std::basic_string<unsigned char> data = (const unsigned char *)"abcdefg";
Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
  • @OliCharlesworth: For a buffer of unsigned chars holding binary data, yes, really. Why not? – Benjamin Lindley Dec 11 '11 at 21:54
  • I'm fine with using a vector. I don't understand why you wouldn't just write `std::vector v(8, '0');`, though. – Oliver Charlesworth Dec 11 '11 at 21:57
  • @OliCharlesworth: I was thinking about if you later wanted to change the string to non-uniform data without worrying about the length of the string. You might want to use sizeof, followed by a copy. – Benjamin Lindley Dec 11 '11 at 21:59
  • @OliCharlesworth: Not this specifically, but as I said above, you follow it with a copy, e.g. : `std::vector v(sizeof("abcdefg") - 1); std::copy_n("abcdefg", sizeof("abcdefg") - 1, v.begin());` -- Okay, I realize now that I've typed that, it's a little more verbose than I was thinking, especially since I had to type "abcdefg" 3 times. But you see what I was thinking now, right? (Fixed it) – Benjamin Lindley Dec 11 '11 at 22:06
1

You're trying to assign string value to pointer to unsigned char. You cannot do that. If you have pointer, you can assign only memory address or NULL to that.

Use const char instead.

Tomáš Plešek
  • 1,482
  • 2
  • 12
  • 21
1

Your target variable is a pointer to an unsigned char. "00000000" is a string literal. It's type is const char[9]. You have two type mismatches here. One is that unsigned char and char are different types. The lack of a const qualifier is also a big problem.

You can do this:

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

But this is something you should not do. Ever. Casting away the constness of a string literal will get you in big trouble some day.

The following is a little better, but strictly speaking it is still unspecified behavior (maybe undefined behavior; I don't want to chase down which it is in the standard):

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

Here you are preserving the constness but you are changing the pointer type from char* to unsigned char*.

David Hammen
  • 32,454
  • 9
  • 60
  • 108
0

@Holland -

unsigned char * data = "00000000"; 

One very important point I'm not sure we're making clear: the string "00000000\0" (9 bytes, including delimiter) might be in READ-ONLY MEMORY (depending on your platform).

In other words, if you defined your variable ("data") this way, and you passed it to a function that might try to CHANGE "data" ... then you could get an ACCESS VIOLATION.

The solution is:

1) declare as "const char *" (as the others have already said)

  ... and ...

2) TREAT it as "const char *" (do NOT modify its contents, or pass it to a function that might modify its contents).

paulsm4
  • 114,292
  • 17
  • 138
  • 190