tags:

views:

87

answers:

4

Hi, I want to take a string,and populate an array with its values. I know the length of the string is 16. I have tried

char *bit_number[16];
bit_number = bin.data();

and

char bit_number[16];
bit_number = bin.data();

I don't understand what String.data() is returning, why can't I assign it directly to an array? I'm getting compiler errors:

error: incompatible types in assignment of ‘const char*’ to ‘char* [16]’

and

error: incompatible types in assignment of ‘const char*’ to ‘char [16]’
+4  A: 

You need to copy the contents:

Assuming bin is a std::string:

char bit_numer[16];
copy( bin.begin(), bin.end(), bit_number );

This is all kinds of risky, however. What if your bin has 17 characters ?

By the way, your original code:

char *bit_number[16];

...doesn't allocate an array of 16 chars as you may expect. It allocated an array of 16 char*. Most probably not what you're wanting.

John Dibling
@sbi: LOL how many up-votes are the limit? I'm embarassed to say I've never reached it. :)
John Dibling
+1 for cleanest solution
Steve Townsend
+1  A: 

If you want the dest array null-terminated, that's an extra line of code, and maybe an extra byte in your target array to accommodate it.

In your first example you have an array of 16 pointers to char. That's not what you want.

In your second example you have the types correct but you cannot assign the pointer (returned from data()) directly to the array because their types are not compatible - you have to copy the referenced data from one location to the other.

Steve Townsend
+1  A: 

You can use std::string::c_str() to get access to the char array, and then use strcpy to move it over to the new array.

string s = "1234";
char arr[5] = { 0 };
strcpy(arr, s.c_str());
Paul
Why in the love of twinkies would you use `strcpy` when `copy` is right there, waiting for you to use it?
John Dibling
@John: `copy` doesn't copy the null terminator. If you're working with strings this is pretty important (though, you could get around this by initializing the array to 0 as I did above).
Paul
@Paul: the questioner *says* that the length of the string is 16, and the size of the destination array is also 16. So copying the NUL terminator results in buffer overflow. Whether the questioner *intended* that the array doesn't have room for a terminator, is another matter. You've made the array 1 bigger, perhaps subconsciously and almost certainly correctly :-)
Steve Jessop
@John: for that matter, why would you use `copy` when `strcpy` is right there? You have to avoid Buridan's ass somehow.
Steve Jessop
@Steve: +1 for giving me somethign I had to google. :)
John Dibling
If the variable "bin" stands for "binary", then it's possible that the string will contain a '\0', in which case `bin.data()` and `std::copy()` or `memcpy()` would be the correct answer.
Steve M
@Steve Jessop: Because `std::copy()` is more general than `std::strcpy()`? It works with all kinds of data (including binary) data); it uses the STL's order for parameters (src, src, target), which you'll find more often nowadays as a C++ programmer; there's also `copy_if()`, in case you need it... I don't think I've used `std::strcpy()` since I wrote the last of my own string classes somewhere in the 90ies.
sbi
A: 

What do you need that char array for, anyway? And are you sure whatever is in you string will fit into it? (There's a whole class of bugs coming from the use of arrays, and a famous one, too: buffer overruns.) You're very likely much better off using std::vector, which resizes dynamically:

std::vector<char> v( bin.begin(), bin.end() );

If you need the array to pass it to a C API function that doesn't know how to handle a std::vector, you can access the underlying array of the vector by doing the somewhat cryptic &v[0] or &*v.begin(). (Beware that you must check whether the vector is not empty before accessing its first element that way.)

sbi
`<sigh>` So what's wrong with this? (You _did_ have a reason for down-voting, didn't you?)
sbi