C语言 将 char* 转换为无符号 char*

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6940214/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 09:18:37  来源:igfitidea点击:

Converting char* to unsigned char*

ccharsha1unsignedstrcpy

提问by Rajiv

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. I get the following warning using the above code

我想正确地将 char* 数组复制到 unsigned char* 数组。我使用上面的代码收到以下警告

warning: pointer targets in passing argument 1 of astrncpya 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.

编辑:添加更多信息,我的要求是调用者在命令行上将 SHA 摘要作为字符串提供给主函数,并且主函数在内部将其保存在摘要中。SHA 摘要最好使用无符号字符表示。

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*.

现在的问题是我无法更改主函数 (** char) 的签名,因为主函数将它需要的其他参数解析为 char* 而不是 unsigned char*。

采纳答案by Oliver Charlesworth

To avoid the compiler warning, you simply need:

为了避免编译器警告,您只需要:

strncpy((char *)digest, argv[2], 20);

But avoiding the compiler warning is often nota good idea; it's telling you that there is a fundamental incompatibility. In this case, the incompatibility is that charhas a range of -128 to +127 (typically), whereas unsigned charis 0 to +255.

但是避免编译器警告通常不是一个好主意。它告诉你存在根本的不兼容。在这种情况下,不兼容char的范围是 -128 到 +127(通常),而范围unsigned char是 0 到 +255。

回答by Petr Abdulin

You can't correctlycopy 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 memcpyfunction.

如果您需要复制argv[2]数组的原始位,您应该使用memcpy函数。

回答by pmg

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. 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.

另请注意,这malloc(20 * sizeof(unsigned char*))可能不是您想要的。我认为您想要malloc(20 * sizeof(unsigned char)), 或者,根据定义sizeof (unsigned char)1, malloc(20)。如果您真的想在调用中使用每个元素的大小,请使用对象本身,就像我上面的代码一样。

回答by cyber_raj

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 指针指向的底层对象类型与此函数无关。

回答by George Koehler

There is no one way to convert char *to unsigned char *. They point to data, and you must know the format of the data.

没有一种方法可以转换char *unsigned char *. 它们指向数据,您必须知道数据的格式。

There are at least 3 different formats for a SHA-1 hash:

SHA-1 散列至少有 3 种不同的格式:

  • the raw binary digest as an array of exactly 20 octets
  • the digest as a hexadecimal string, like "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4"
  • the digest as a Base64 string, like "5en6G6MezRroT3XKqkdPOmY/BfQ="
  • 原始二进制摘要作为正好 20 个八位字节的数组
  • 摘要作为十六进制字符串,例如 "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4"
  • 摘要作为 Base64 字符串,例如 "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. I guess that the unsigned char *points to a binary digest.

malloc(20 * sizeof(unsigned char))具有二进制摘要的确切大小,但太小而无法容纳十六进制字符串或 Base64 字符串。我猜这unsigned char *指向二进制摘要。

But the char *came from the command-line arguments of main(), so the char *probably points to a string. Command-line arguments are always C strings; they end with the NUL terminator '\0'and never contain '\0'in the string. Raw binary digests might contain '\0', so they don't work as command-line arguments.

但是char *来自 的命令行参数main(),所以char *可能指向一个字符串。命令行参数始终是 C 字符串;它们以 NUL 终止符结尾,'\0'并且永远不会包含'\0'在字符串中。原始二进制摘要可能包含'\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. The strncpy(3)function stops copying if it finds a '\0'; so if your digest contains '\0', you lose part of the digest.

不要strncpy(dst, src, 20)用于复制原始二进制摘要。的函数strncpy(3)功能停止,如果它发现一个复制'\0'; 因此,如果您的摘要包含'\0',您将丢失部分摘要。

回答by Johnny camargo

Just put (char*)in front of it or (unsigned char*)

放在(char*)它前面或(unsigned char*)

回答by Sandeep Pathak

Warning is simply what it says , you are passing an unsigned char * digest to strncpy function which is in different signedness from what it expects.

警告就是它所说的,您正在将一个 unsigned char * 摘要传递给 strncpy 函数,该函数的符号与它期望的不同。