2016-12-16 24 views
0

私は言葉で達成しようとしているものをどのように置くべきか分かりませんが、私はちょうど下の例を載せて、皆さんが私に手を貸してくれることを願っています!uint_64の16進表現を16進数の符号なし文字配列にコピーする方法は?

基本的には、16進数のuint64_t値の16進数表現を符号なし文字配列にコピーしようとしています。私が持っているもの

:私は途中で先の配列にSRCから値をコピーするにはどうすればよい

uint64_t src; 
unsigned char destination[8]; 
/* codes omitted, some codes that will change the value of src */ 
printf("src: %"PRIx64"\n", src); //this prints out src: 3132333435363738 

こと:

destination[0] = 0x31; 
destination[1] = 0x32; 
destination[2] = 0x33; 
//and so on... 

ありがとう!

EDIT

私は私の質問が不明である場合は申し訳ないが、私はプログラミングに非常に新しいですし、私は自分自身を説明するのに苦労しています。 基本的には、printf()から出力されたものを16進数のunsigned char配列に格納しようとしています。

たとえば、printf()は "3132333435363738"の文字列を出力します.31を取り出してdst [0]に格納します。ここで、dst [0]の値は0x31になります。 ]は0x32になります。

私に感謝してください!

+2

ループアウトマスキングし、必要に応じてバイトをシフトします。 –

+0

@Someprogrammerdude気づいてくれてありがとう!私はそれを変更しましたが、私の質問は同じです。 –

+0

あなたの質問は不明です。 'src'がちょうど' 1'であるとします。 'destination [0]'とは何でしょうか? –

答えて

0

あなたはuint64_t自体を指すようにポインタを設定することができます。

uint64_t src; 
unsigned char *view; 

view = (unsigned char *)&src; 
for (size_t i = 0; i < sizeof(src); ++i) { 
    printf("%x", view[i]); 
} 
printf("\n"); 

をあなたはそれを別のビューを持っていない、コピー値に必要がある場合は、同じ原則が適用されます。

uint64_t src; 
unsigned char dst[sizeof(src)]; 
memcpy((void *)&dst, (void *)&src, sizeof(src)); 
for (size_t i = 0; i < sizeof(src); ++i) { 
    printf("%x", dst[i]); 
} 
printf("\n"); 

これは、プラットフォームのネイティブエンディアンを継承することに注意してください。エンディアンを変換する場合は、文字列を表示/コピーする前にsrcにライブラリ関数uint64_t htobe64(uint64_t x)(Linux、BSD)またはOSSwapHostToBigInt64(x)(OS X)を使用することができます。私はWindowsの同等物を知らないが、彼らはそれらを持っていると思う。符号拡張の問題を避けるため、charの代わりにunsigned charを使用しました。

+0

@WhozCraig:ありがとう、固定。それは私がテストなしで投稿するために得るものです。 – mtrw

+0

@Stargateur:ありがとう、libiの情報を追加してendiannesを変換しました。 – mtrw

+0

固定幅の出力を提案する 'printf("%02x "、view [i]);' – chux

3

与えられた順序で整数を構成するバイトを抽出する簡単かつ移植可能な方法は、ビットシフト(および場合によってはマスク)を使用することです。あなたのケースでは、あなたはそれは次のようになりので、ビッグエンディアン順(srcdestination =>最上位バイトの最初のバイト)で、あなたのバイトを抽出したいように見える:

uint64_t src; 
unsigned char destination[8]; 
for(int i=0; i<8; ++i) { 
    destination[i] = src>>((7-i)*8); 
} 

各反復において、srcがシフトしています(7-I)* 8ビットだけ右に、私たちは希望のバイトに行きたいので、「下部の」結果の

最初の反復:

src = 0x123456789abcdef0; 
i = 0 
(7-i) = 7 
src >> ((7-i)*8) = 0x12 

ので、我々は0x12をし、我々ましたdestination[0]に入れてください。次の反復で、我々は今

i = 1 
(7-i) = 6 
src >> ((7-i)*8) = 0x1234 

を持って、我々は底部のみ8ビットを取るために0xFFに結果をマスクすることができ(すなわち、0x34の)、それはそれぞれの要素以来、私たちの場合は重要ではありませんdestinationであり、符号なしバイトなので、255を超える値を割り当てると(この場合)、符号なしオーバーフローが発生します。これは、ターゲットに「フィット」する下位バイトのみを使用するように定義されています。 so、destination[1]=0x34

これをiまで繰り返すと、必要な結果が得られます。

+0

@LightnessRacesinOrbit:申し訳ありません、私は急いでいて、ここで多くの誤情報が発生していました。私はいくつかの解説を追加します。 –

0

ポインターキャスト+ポインター演算を使用するソリューション、またはユニオンを使用するソリューションは移植できません。

これは、エンディアンにかかわらず、この移植性を簡単に実現する方法です。より効果的な方法があるかもしれません。

#include <stdio.h> 
#include <stdint.h> 
#include <inttypes.h> 
#include <stdbool.h> 

int main(void) 
{ 
    uint64_t src; 
    uint8_t destination[8] = {0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38}; 

    const uint16_t dummy = 1; 
    const bool is_little_endian = *(const uint8_t*)&dummy == 1; 

    src=0; 
    for(size_t i=0; i<8; i++) 
    { 
    size_t shift = i*8; 

    if(is_little_endian) 
    { 
     shift = 64-8-shift; 
    } 

    src |= (uint64_t)destination[i] << shift; 
    } 

    printf("%" PRIx64, src); 

    return 0; 
} 
0

これは、本質的に、固定幅型uint8_t代わりにunsigned charに@Matteoイタリアで与えられる溶液が、マスクを使用して明示的なキャストと同じです。これらのソリューションは、エンディアンに関係なく動作するはずです。なぜなら、ビット単位の演算子は、その元の表現ではなく、左のオペランドの値に作用するからです。

#include <stdio.h> 
#include <stdint.h> 
#include <inttypes.h> 

int main(void) 
{ 
    uint64_t src = 0x3132333435363738; 
    uint8_t destination[8]; 
    uint64_t mask = 0xff << 56; 
    size_t i; 

    for (i = 0; i < 8; i++) { 
     destination[i] = (uint8_t) ((src & mask) >> (56 - i * 8)); 
     mask >>= 8; 
    } 

    printf("src: 0x%" PRIx64 "\n", src); 

    for (i = 0; i < 8; i++) { 
     printf("destination[%zu] = 0x%" PRIx8 "\n", i, destination[i]); 
    } 

    return 0; 
} 

出力は:

src: 0x3132333435363738 
destination[0] = 0x31 
destination[1] = 0x32 
destination[2] = 0x33 
destination[3] = 0x34 
destination[4] = 0x35 
destination[5] = 0x36 
destination[6] = 0x37 
destination[7] = 0x38 
関連する問題