21

Cでchar*をunsignedchar*に正しくコピーするにはどうすればよいですか。以下は私のコードです。

int main(int argc, char **argv)
{
    unsigned char *digest;

    digest = malloc(20 * sizeof(unsigned char));
    strncpy(digest, argv[2], 20);
    return 0;
}

char*配列をunsignedchar*配列に正しくコピーしたいと思います。上記のコードを使用すると、次の警告が表示されます

warning: pointer targets in passing argument 1 of âstrncpyâ differ in signedness 

編集:さらに情報を追加します。私の要件は、呼び出し元がコマンドラインで文字列としてメイン関数にSHAダイジェストを提供し、メイン関数がそれをダイジェストに内部的に保存することです。SHAダイジェストは、unsignedcharを使用して最もよく表すことができます。

ここでの問題は、main関数がunsigned char*ではなくchar*として必要な他の引数を解析するため、main関数(** char)の署名を変更できないことです。

4

7 に答える 7

15

コンパイラの警告を回避するには、次のものが必要です。

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

しかし、多くの場合、コンパイラの警告を回避することはお勧めできません。根本的な非互換性があることを示しています。この場合、非互換性はchar-128 から +127 (通常) の範囲で、unsigned char0 から +255 です。

于 2011-08-04T11:09:23.827 に答える
6

タイプに違いがあるため、正しくコピーできません。コンパイラはそれについて警告します。

argv[2]配列の生のビットをコピーする必要がある場合は、memcpy関数を使用する必要があります。

于 2011-08-04T11:08:57.610 に答える
2

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). 呼び出しで各要素のサイズを本当に使用したい場合は、上記のコードのように、オブジェクト自体を使用してください。

于 2011-08-04T11:15:34.920 に答える
1

memcpy は次のように使用できます。

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

src ポインターと dest ポインターが指すオブジェクトの基本的な型は、この関数には関係ないためです。

于 2011-08-04T11:21:02.900 に答える
1

その前に置く(char*)か、(unsigned char*)

于 2018-06-09T00:50:00.477 に答える
1

に変換char *する方法は 1 つではありませんunsigned char *。それらはデータを指しており、データの形式を知っている必要があります。

SHA-1 ハッシュには、少なくとも 3 つの異なる形式があります。

  • 正確に 20 オクテットの配列としての生のバイナリ ダイジェスト
  • のような 16 進文字列としてのダイジェスト"e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4"
  • のような Base64 文字列としてのダイジェスト"5en6G6MezRroT3XKqkdPOmY/BfQ="

malloc(20 * sizeof(unsigned char))バイナリ ダイジェストの正確なサイズがありますが、小さすぎて 16 進文字列または Base64 文字列に収まりません。unsigned char *バイナリダイジェストを指していると思います。

しかし、char *は のコマンドライン引数に由来するmain()ため、 はchar *おそらく文字列を指しています。コマンドライン引数は常に C 文字列です。それらは NUL ターミネータで終わり、文字列'\0'に含まれることはありません'\0'。生のバイナリ ダイジェストには が含まれている可能性が'\0'あるため、コマンド ライン引数としては機能しません。

SHA-1 ダイジェストを 16 進数文字列から生のバイナリに変換するコードは次のようになります。

#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'の一部が失われます。

于 2017-09-23T05:05:32.430 に答える
0

警告は単にそれが言うことです.unsigned char *ダイジェストをstrncpy関数に渡していますが、これは予想とは異なる符号です。

于 2011-08-04T11:10:14.807 に答える