C 将字符*转换为无符号字符*
如何在C中正确地将字符*复制到无符号字符*。下面是我的代码C 将字符*转换为无符号字符*,c,char,sha1,unsigned,strcpy,C,Char,Sha1,Unsigned,Strcpy,如何在C中正确地将字符*复制到无符号字符*。下面是我的代码 int main(int argc, char **argv) { unsigned char *digest; digest = malloc(20 * sizeof(unsigned char)); strncpy(digest, argv[2], 20); return 0; } 我想将char*数组正确复制到unsigned char*数组。我使用上面的代码得到以下警告 warning: po
int main(int argc, char **argv)
{
unsigned char *digest;
digest = malloc(20 * sizeof(unsigned char));
strncpy(digest, argv[2], 20);
return 0;
}
我想将char*数组正确复制到unsigned char*数组。我使用上面的代码得到以下警告
warning: pointer targets in passing argument 1 of âstrncpyâ differ in signedness
编辑:添加更多信息,我的要求是调用方在命令行上以字符串形式向主函数提供SHA摘要,主函数在内部将其保存在摘要中。SHA摘要最好使用无符号字符表示
现在的问题是,我无法更改主函数(**char)的签名,因为主函数将它需要的其他参数解析为char*,而不是unsigned char*您无法正确地复制它,因为类型不同,编译器警告您这一点
如果需要复制
argv[2]
数组的原始位,则应使用memcpy
函数。为避免编译器警告,只需:
strncpy((char *)digest, argv[2], 20);
但是避免编译器警告通常不是一个好主意;它告诉你有一个基本的不相容性。在这种情况下,不兼容之处在于
char
的范围为-128到+127(通常),而unsigned char
的范围为0到+255。警告就是这么说的,您正在将一个unsigned char*摘要传递给strncpy函数,该函数的符号与预期的符号不同 在strncpy()调用中丢弃签名
strncpy((char*)digest, argv[2], 20);
或者引入另一个变量
#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;
}
#包括
#包括
int main(int argc,字符**argv)
{
无符号字符*摘要;
void*tmp;/*(void*)与(char*)和(unsigned char*)兼容*/
摘要=malloc(20*sizeof*digest);
国际单项体育联合会(摘要){
tmp=摘要;
如果(argc>2)strncpy(tmp,argv[2],20);
免费(摘要);
}否则{
fprintf(stderr,“无内存。\n”);
}
返回0;
}
还要注意,malloc(20*sizeof(unsigned char*))
可能不是您想要的。我想你想要malloc(20*sizeof(unsigned char))
,或者,根据定义sizeof(unsigned char)
是1
,malloc(20)
。
如果您确实想在调用中使用每个元素的大小,请使用对象本身,如上面的代码所示。您可以将memcpy用作:
memcpy(digest, argv[2], strlen(argv[2]) + 1);
由于src和dest指针指向的对象的基本类型与此函数无关。没有一种方法可以将char*
转换为无符号char*
。它们指向数据,您必须知道数据的格式
SHA-1哈希至少有3种不同的格式:
- 原始二进制摘要作为正好由20个八位字节组成的数组
- 摘要为十六进制字符串,如“e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4”
“5en6g6mezrot3xkqkdpomy/BfQ=“
malloc(20*sizeof(unsigned char))
具有二进制摘要的精确大小,但太小,无法容纳十六进制字符串或Base64字符串。我猜无符号字符*
指向一个二进制摘要
但是char*
来自main()
的命令行参数,因此char*
可能指向一个字符串。命令行参数始终是C字符串;它们以NUL终止符'\0'
结尾,并且字符串中从不包含'\0'
。原始二进制摘要可能包含'\0'
,因此它们不能用作命令行参数
将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;
}
#包括
#包括
无符号字符*
sha1_from_hex(字符*hex)
{
int i,m,n,八位组;
无符号字符*摘要;
摘要=malloc(20);
如果(!摘要)
返回NULL;
对于(i=0;i<20;i++){
sscanf(十六进制,“%n%2x%n”、&m、&八进制,&n);
如果(m!=0 | | n!=2)
走向失败;
摘要[i]=八位字节;
十六进制+=2;
}
如果(*十六进制)
走向失败;
返回摘要;
失败:
免费(摘要);
返回NULL;
}
不要使用strncpy(dst,src,20)
复制原始二进制摘要。如果发现'\0'
,函数将停止复制;因此,如果您的摘要包含“\0”
,您将丢失部分摘要。只需将(char*)
放在它前面即可
或者
(unsigned char*)
是的,这就是问题所在,我如何以更好的方式解决不兼容问题?如果您能告诉我们为什么需要in作为unsigned char,这可能会帮助我们回答这个问题?为了猜测更好的解决方案,您可能应该使用一个结构或联合,而不是一团无符号字符内存。在char*
vsunsigned char*
的情况下,警告(根据标准,编译器应该将其视为错误!)除了标准中的错误外,很少指示任何错误。几乎所有的标准函数都采用char*
,但处理的数据实际上被视为无符号char的数组。请参见strcmp
@R..:你说“被当作无符号字符的数组处理”是什么意思?我举了strcmp
为例。它需要根据解释为无符号字符的第一个不匹配字节之间的差异进行比较。IMO在这里引入伪变量只是混淆了代码,没有相应的好处。OP显然想要“比强制转换更好的方法”。模糊化的(void*)
变量以另一种方式完成:我将把决定权留给OP(像你一样,@Oli,我认为不是)。哈希摘要通常表示为摘要十六进制值的ASCII表示(例如“b6379dab2c…
”)。一个char
绝对可以@因此,演员阵容基本上也可以正常工作,不会出现任何问题。((char*)摘要,argv[2],20);罪