A string (char array) in C is a sequencial sequence of chars terminated by a sentianal character (the null terminator: '\0')
This means that if you have a byte of the value 0x00 anywhere in your array, it has thusly terminated the "string" potentially before the end of the sequence. In your example if you converted your data array into a string the end of it would be the first element:
data[]{00, EB, 23, EC, FF, etc... };
Now if you want to make a string out of the values of the data in here, you can do that with sprintf(), for example:
unsigned char val = 00;
data[0] = val;
char dump[5] = {0};
sprintf(dump, "%02x", data[0]);
Now you have a string with the value "00" in it, You can make it fancer with something like:
sprintf(dump, "0x%02x", data[0]);
So that it has "0x00" to show it off as hex data.
You could loop something like this to give the full string... but keep in mind that the printable string needs to be at least 2x+1 the size of the data string (2x for ASCII and +1 for null), and you have to fill the new string in steps. Example:
unsigned char data[5] = {0x00, 0x12, 0xB3, 0xFF, 0xF0};
char printstr[11] = {00};
for(int x = 0; x < 5; x++)
sprintf(printstr+(x*2), "%02x", data[x]);
printstr[10] = '\0';
Now printstr has "0012b3fff0"
A string (char array) in C is a sequencial sequence of chars terminated by a sentianal character (the null terminator: '\0')
This means that if you have a byte of the value 0x00 anywhere in your array, it has thusly terminated the "string" potentially before the end of the sequence. In your example if you converted your data array into a string the end of it would be the first element:
data[]{00, EB, 23, EC, FF, etc... };
Now if you want to make a string out of the values of the data in here, you can do that with sprintf(), for example:
unsigned char val = 00;
data[0] = val;
char dump[5] = {0};
sprintf(dump, "%02x", data[0]);
Now you have a string with the value "00" in it, You can make it fancer with something like:
sprintf(dump, "0x%02x", data[0]);
So that it has "0x00" to show it off as hex data.
You could loop something like this to give the full string... but keep in mind that the printable string needs to be at least 2x+1 the size of the data string (2x for ASCII and +1 for null), and you have to fill the new string in steps. Example:
unsigned char data[5] = {0x00, 0x12, 0xB3, 0xFF, 0xF0};
char printstr[11] = {00};
for(int x = 0; x < 5; x++)
sprintf(printstr+(x*2), "%02x", data[x]);
printstr[10] = '\0';
Now printstr has "0012b3fff0"
you can use sprintf (note if you sprintf past the end of the 'str' array, you will have a buffer overflow):
//malloc 2 chars for each byte of data (for 2 hex digits)
char *str = malloc(sizeof(char) * 3 * (sizeof(data) + 1));
//this var will point to the current location in the output string
char *strp = str;
if (NULL == str)
{
return false; //memory error
}
for (size_t i= 0; i < sizeof(data); i++) {
snprintf(strp, 2, "%02X ", data[i]);
strp++;
}
// now the memory in *str holds your hex string!
C++ how to convert unsigned char array to string? - Stack Overflow
converting unsigned char array to char array
How do I convert an 'unsigned char' to ' - C++ Forum
Convert C unsigned char to string
I've found various different ways of creating strings from unsigned char arrays on StackOverflow etc, however, I couldn't discern the best / most idiomatic way of doing it. I need this for reading lines from memory mapped files.
string MemoryMappedReader::getLine() {
// Null-terminated buffer.
unsigned char buffer[_bufferSize];
fill_n( buffer, _bufferSize, '\0' );
for (int index = 0; (_cursor += index) < _fileSize; index++) {
unsigned char character = _memoryMappedFile[_cursor];
if (character == '\n')
break;
buffer[index] = character;
}
return ""; // I want to return a string representation of buffer
}Any advise?
#include <iomanip>
#include <sstream>
#include <string>
std::ostringstream oss;
for(int i = 0; i < SHA256_DIGEST_LENGTH; ++i)
{
oss << std::hex << std::setw(2) << std::setfill('0') << +c[i];
}
auto str = oss.str();
For printing out hex values, you can use std::hex format; for setting width and fill character, use std::setw and std::setfill, which are part of <iomanip>.
As you do not show the data type of c, I suppose/suggest to use an unsigned integral type, e.g. unsigned char. I slightly adapted the code to make it self contained):
#define SHA256_DIGEST_LENGTH 256
#include <iostream>
#include <sstream>
#include <iomanip>
int main() {
unsigned char c[SHA256_DIGEST_LENGTH];
for (unsigned int i=0; i<SHA256_DIGEST_LENGTH; i++)
c[i]=i;
std::stringstream ss;
for(int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
ss << std::hex << std::setw(2) << std::setfill('0') << (unsigned int)c[i];
}
std::cout << ss.str();
}
Output:
000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
std::string has a constructor that takes a pair of iterators and unsigned char can be converted (in an implementation defined manner) to char so this works. There is no need for a reinterpret_cast.
unsigned char u_array[4] = { 'a', 's', 'd', 'f' };
#include <string>
#include <iostream>
#include <ostream>
int main()
{
std::string str( u_array, u_array + sizeof u_array / sizeof u_array[0] );
std::cout << str << std::endl;
return 0;
}
Of course an "array size" template function is more robust than the sizeof calculation.
Well, apparently std::string has a constructor that could be used in this case:
std::string str(reinterpret_cast<char*>(u_array), 4);
So, based on your update, are you talking about trying to convert a unsigned char buffer into a hexadecimal interpretation, something like this:
#define bufferSize 10
int main() {
unsigned char buffer[bufferSize]={1,2,3,4,5,6,7,8,9,10};
char converted[bufferSize*2 + 1];
int i;
for(i=0;i<bufferSize;i++) {
sprintf(&converted[i*2], "%02X", buffer[i]);
/* equivalent using snprintf, notice len field keeps reducing
with each pass, to prevent overruns
snprintf(&converted[i*2], sizeof(converted)-(i*2),"%02X", buffer[i]);
*/
}
printf("%s\n", converted);
return 0;
}
Which outputs:
0102030405060708090A
In C, a string is an array of char, terminated with a character whose value is 0.
Whether or not char is a signed or unsigned type is not specified by the language, you have to be explicit and use unsigned char or signed char if you really care.
It's not clear what you mean by "representing" an unsigned character array as string. It's easy enough to cast away the sign, if you want to do something like:
const unsigned char abc[] = { 65, 66,67, 0 }; // ASCII values for 'A', 'B', 'C'.
printf("The English alphabet starts out with '%s'\n", (const char *) abc);
This will work, to printf() there isn't much difference, it will see a pointer to an array of characters and interpret them as a string.
Of course, if you're on a system that doesn't use ASCII, there might creep in cases where doing this won't work. Again, your question isn't very clear.
Firstly, the array has to be at least big enough to hold the string:
unsigned char m_Test[20];
then you use strcpy. You need to cast the first parameter to avoid a warning:
strcpy( (char*) m_Test, "Hello World" );
Or if you want to be a C++ purist:
strcpy( static_cast <char*>( m_Test ), "Hello World" );
If you want to initialise the string rather than assign it, you could also say:
unsigned char m_Test[20] = "Hello World";
For all practical purposes, the strcpy answers are correct, with the note that 8 isn't big enough for your string.
If you want to be really pedantic, you might need something like this:
#include <algorithm>
int main() {
const char greeting[] = "Hello world";
unsigned char m_Test[sizeof(greeting)];
std::copy(greeting, greeting + sizeof(greeting), m_Test);
}
The reason is that std::copy will convert the characters in the original string to unsigned char. strcpy will result in the characters in the original string being reinterpreted as unsigned char. You don't say which one you want.
The standard permits there to be a difference between the two, although it's very rare: you'd need char to be signed, in an implementation with a 1s' complement or sign-magnitude representation. You can pretty much ignore the possibility, but IMO it's worth knowing about, because it explains the funny warnings that good compilers give you when you mix up pointers to char and unsigned char.