[英]Converting char* to unsigned char*
How do I copy a char* to a unsigned char* correctly in C. Following is my code 如何在C中正确地将char *复制到unsigned char *。以下是我的代码
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. 我想正确地将char *数组复制到unsigned char *数组。 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摘要作为命令行上的字符串,主函数在内部将其保存在摘要中。 SHA digest can be best represented using a unsigned char.
SHA摘要可以使用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*. 现在的问题是我无法更改main函数(** char)的签名,因为main函数解析了它需要的其他参数作为char *而不是unsigned char *。
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. 在这种情况下,不兼容性是
char
的范围是-128到+127(通常),而unsigned char
是0到+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. 如果你需要复制
argv[2]
数组的原始位,你应该使用memcpy
函数。
Cast the signedness away in the strncpy()
call 在
strncpy()
调用中抛出签名
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. 另请注意,
malloc(20 * sizeof(unsigned char*))
可能不是您想要的。 I think you want malloc(20 * sizeof(unsigned char))
, or, as by definition sizeof (unsigned char)
is 1
, malloc(20)
. 我想你想要
malloc(20 * sizeof(unsigned char))
,或者,如定义sizeof (unsigned char)
是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. 如果你真的想要使用调用中每个元素的大小,请使用对象本身,就像我上面的代码一样。
You can use memcpy as: 您可以使用memcpy:
memcpy(digest, argv[2], strlen(argv[2]) + 1);
as the underlying type of objects pointed to by src and dest pointers are irrelevant for this function. 因为src和dest指针指向的基础对象类型与此函数无关。
There is no one way to convert char *
to unsigned char *
. 没有一种方法可以将
char *
转换为unsigned char *
。 They point to data, and you must know the format of the data. 它们指向数据,您必须知道数据的格式。
There are at least 3 different formats for a SHA-1 hash: SHA-1哈希至少有3种不同的格式:
"e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4"
"e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4"
"5en6G6MezRroT3XKqkdPOmY/BfQ="
"5en6G6MezRroT3XKqkdPOmY/BfQ="
Your malloc(20 * sizeof(unsigned char))
has the exact size of a binary digest, but is too small to fit a hexadecimal string or a Base64 string. 您的
malloc(20 * sizeof(unsigned char))
具有二进制摘要的确切大小,但是太小而不适合十六进制字符串或Base64字符串。 I guess that the unsigned char *
points to a binary digest. 我想
unsigned char *
指向二进制摘要。
But the char *
came from the command-line arguments of main()
, so the char *
probably points to a string. 但
char *
来自main()
的命令行参数,因此char *
可能指向一个字符串。 Command-line arguments are always C strings; 命令行参数始终是C字符串; they end with the NUL terminator
'\\0'
and never contain '\\0'
in the string. 它们以NUL终止符
'\\0'
结尾,并且从不在字符串中包含'\\0'
。 Raw binary digests might contain '\\0'
, so they don't work as command-line arguments. 原始二进制摘要可能包含
'\\0'
,因此它们不能用作命令行参数。
The code to convert a SHA-1 digest from hexadecimal string to raw binary might look like 将SHA-1摘要从十六进制字符串转换为原始二进制文件的代码可能如下所示
#include <stdio.h>
#include <stdlib.h>
unsigned char *
sha1_from_hex(char *hex)
{
int i, m, n, octet;
unsigned char *digest;
digest = malloc(20);
if (!digest)
return NULL;
for (i = 0; i < 20; i++) {
sscanf(hex, " %n%2x%n", &m, &octet, &n);
if (m != 0 || n != 2)
goto fail;
digest[i] = octet;
hex += 2;
}
if (*hex)
goto fail;
return digest;
fail:
free(digest);
return NULL;
}
Don't use strncpy(dst, src, 20)
to copy raw binary digests. 不要使用
strncpy(dst, src, 20)
来复制原始二进制摘要。 The strncpy(3) function stops copying if it finds a '\\0'
; strncpy(3)函数如果找到
'\\0'
则停止复制; so if your digest contains '\\0'
, you lose part of the digest. 因此,如果您的摘要包含
'\\0'
,则会丢失部分摘要。
只需将(char*)
放在它前面或(unsigned char*)
警告就是它所说的,你将一个unsigned char *摘要传递给strncpy函数,该函数与它预期的符号不同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.