How do I copy a char* to a unsigned char* correctly in C. Following is my code
int main(int argc, char **argv)
{
unsigned char *digest;
digest = malloc(20 * sizeof(unsigned char));
strncpy(digest, argv[2], 20);
return 0;
}
I would like to correctly copy char* array to unsigned char* array. I get the following warning using the above code
warning: pointer targets in passing argument 1 of âstrncpyâ differ in signedness
EDIT: Adding more information, My requirement is that the caller provide a SHA digest to the main function as a string on command line and the main function internally save it in the digest. SHA digest can be best represented using a unsigned char.
Now the catch is that I can't change the signature of the main function (** char) because the main function parses other arguments which it requires as char* and not unsigned char*.
Yes, given your program's semantics, you can safely cast an array of signed chars to a pointer to unsigned char, with which you effectively say, this memory is not an array of signed chars, but an array of unsigned chars.
unsigned char is a character datatype where the variable consumes all the 8 bits of the memory and there is no sign bit (which is there in signed char). So it means that the range of unsigned char data type ranges from 0 to 255.
If it exists, uint8_t must always have the same width as unsigned char . However, it need not be the same type; it may be a distinct extended integer type. It also need not have the same representation as unsigned char ; for instance, the bits could be interpreted in the opposite order.
To avoid the compiler warning, you simply need:
strncpy((char *)digest, argv[2], 20);
But avoiding the compiler warning is often not a good idea; it's telling you that there is a fundamental incompatibility. In this case, the incompatibility is that char
has a range of -128 to +127 (typically), whereas unsigned char
is 0 to +255.
You can't correctly copy it since there is difference in types, compiler warns you just about that.
If you need to copy raw bits of argv[2]
array you should use memcpy
function.
Cast the signedness away in the strncpy()
call
strncpy((char*)digest, argv[2], 20);
or introduce another variable
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
unsigned char *digest;
void *tmp; /* (void*) is compatible with both (char*) and (unsigned char*) */
digest = malloc(20 * sizeof *digest);
if (digest) {
tmp = digest;
if (argc > 2) strncpy(tmp, argv[2], 20);
free(digest);
} else {
fprintf(stderr, "No memory.\n");
}
return 0;
}
Also note that malloc(20 * sizeof(unsigned char*))
is probably not what you want. I think you want malloc(20 * sizeof(unsigned char))
, or, as by definition sizeof (unsigned char)
is 1
, malloc(20)
.
If you really want to use the size of each element in the call, use the object itself, like in my code above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With