Преобразование char * в unsigned char * - PullRequest
18 голосов
/ 04 августа 2011

Как мне правильно скопировать char * в unsigned char * на 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: pointer targets in passing argument 1 of âstrncpyâ differ in signedness 

EDIT : добавив больше информации, я требую, чтобы вызывающая сторона предоставляла дайджест SHA для главной функции в виде строки в командной строкеи основная функция внутренне сохраняет его в дайджесте.Дайджест SHA лучше всего представить с использованием знака без знака.

Теперь выгода в том, что я не могу изменить сигнатуру основной функции (** char), потому что функция main анализирует другие аргументы, которые ей требуются как char* а не беззнаковый символ *.

Ответы [ 7 ]

11 голосов
/ 04 августа 2011

Чтобы избежать предупреждения компилятора, вам просто необходимо:

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

Но избегать предупреждения компилятора часто не хорошая идея;это говорит вам, что есть фундаментальная несовместимость.В этом случае несовместимость заключается в том, что char имеет диапазон от -128 до +127 (обычно), тогда как unsigned char составляет от 0 до + 255.

5 голосов
/ 04 августа 2011

Вы не можете правильно скопировать его, поскольку есть различия в типах, компилятор предупреждает вас именно об этом.

Если вам нужно скопировать необработанные биты массива argv[2], вам следует использовать функцию memcpy.

2 голосов
/ 04 августа 2011

Откажитесь от подписи в 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;
}

Также обратите внимание, что malloc(20 * sizeof(unsigned char*)), вероятно, не то, что вы хотите. Я думаю, что вы хотите malloc(20 * sizeof(unsigned char)), или, как по определению sizeof (unsigned char) это 1, malloc(20). Если вы действительно хотите использовать размер каждого элемента в вызове, используйте сам объект, как в моем коде выше.

1 голос
/ 04 августа 2011

Вы можете использовать memcpy как:

memcpy(digest, argv[2], strlen(argv[2]) + 1);

, так как базовый тип объектов, на которые указывают указатели src и dest, не имеет значения для этой функции.

0 голосов
/ 09 июня 2018

Просто поставьте (char*) перед ним или (unsigned char*)

0 голосов
/ 23 сентября 2017

Нет способа конвертировать char * в unsigned char *.Они указывают на данные, и вы должны знать формат данных.

Существует как минимум 3 различных формата для хэша SHA-1:

  • необработанный двоичный дайджест в видемассив из точно 20 октетов
  • дайджест в виде шестнадцатеричной строки, например "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4"
  • дайджест в виде строки Base64, например "5en6G6MezRroT3XKqkdPOmY/BfQ="

Ваш malloc(20 * sizeof(unsigned char)) имеет точный размер двоичного дайджеста, но слишком мал для размещения шестнадцатеричной строки или строки Base64.Я предполагаю, что unsigned char * указывает на двоичный дайджест.

Но 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;
}

Не используйте strncpy(dst, src, 20) для копирования сырых двоичных дайджестов.Функция strncpy (3) прекращает копирование, если находит '\0';поэтому, если ваш дайджест содержит '\0', вы потеряете часть дайджеста.

0 голосов
/ 04 августа 2011

Предупреждение - это просто то, что написано: вы передаете неподписанный символ char * в функцию strncpy, которая отличается от того, что она ожидает.

...