1

私の CS コースの一環として、使用する関数がいくつか与えられました。これらの関数の 1 つは unsigned chars へのポインターを使用して、ファイルにデータを書き込みます (この関数を使用する必要があるため、異なる動作をする独自の専用関数を作成することはできません)。この関数を使用して、値が最大 4095 の整数の配列を書き込む必要があります (符号なし文字のみを使用します)。

しかし、unsigned char は 1 バイトの長さであるため、最大値は 256 しか持てないと考えるのは正しいでしょうか? したがって、整数ごとに4つの符号なし文字を使用する必要がありますか? しかし、キャストは整数のより大きな値では機能しないようです。整数の配列を符号なし文字に変換する最善の方法を知っている人はいますか?

4

7 に答える 7

5

通常、unsigned char は 8 ビットを保持し、最大値は 255 です。特定のコンパイラについてこれを知りたい場合は、CHAR_BIT と UCHAR_MAX を出力してください<limits.h> 。32 ビット int の個々のバイトを抽出できます。

#include <stdint.h>

void
pack32(uint32_t val,uint8_t *dest)
{
        dest[0] = (val & 0xff000000) >> 24;
        dest[1] = (val & 0x00ff0000) >> 16;
        dest[2] = (val & 0x0000ff00) >>  8;
        dest[3] = (val & 0x000000ff)      ;
}


uint32_t
unpack32(uint8_t *src)
{
        uint32_t val;

        val  = src[0] << 24;
        val |= src[1] << 16;
        val |= src[2] <<  8;
        val |= src[3]      ;

        return val;
}
于 2011-01-07T20:50:36.757 に答える
3

unsigned charの値は通常1バイトであるため、他のタイプをunsigned charの配列に分解できます(たとえば、4バイトのintの場合、4つのunsigned charの配列を使用できます)。あなたの演習はおそらくジェネリックに関するものです。fwrite()関数を使用してファイルをバイナリファイルとして書き込み、ファイルにバイトごとに書き込む必要があります。

次の例では、(任意のデータ型の)数値をファイルに書き込む必要があります。キャストをvoid*ではなくunsignedchar*に強制しているため、機能するかどうかはわかりません。

int homework(unsigned char *foo, size_t size)
{
    int i;

    // open file for binary writing
    FILE *f = fopen("work.txt", "wb");
    if(f == NULL)
        return 1;

    // should write byte by byte the data to the file
    fwrite(foo+i, sizeof(char), size, f);

    fclose(f);
    return 0;
}

与えられた例が少なくともあなたに出発点を与えることを願っています。

于 2011-01-07T21:17:56.403 に答える
0

はい、あなたが正しい; 文字/バイトは最大 8 つの異なるビットしか許可しないため、2^8 の異なる数値であり、0 から 2^8 - 1、または 0 から 255 です。バイトを取得するには、次のようにします。

int x = 0;
char* p = (char*)&x;
for (int i = 0; i < sizeof(x); i++)
{
    //Do something with p[i]
}

(これは、宣言の順序のために正式に C ではありませんが、何でも...より読みやすいです。:))

このコードは、 のプロセッサの内部ストレージに依存するため、移植できない場合があることに注意してくださいint

于 2011-01-07T20:23:44.163 に答える
0

引数、戻り値、およびセマンティクス (つまり、その動作の定義) に関して使用するように指示されている関数に関する情報がなければ、答えるのは困難です。1 つの可能性は次のとおりです。

与えられた:

void theFunction(unsigned char* data, int size);

それから

int array[SIZE_OF_ARRAY];
theFunction((insigned char*)array, sizeof(array));

また

theFunction((insigned char*)array, SIZE_OF_ARRAY * sizeof(*array));

また

theFunction((insigned char*)array, SIZE_OF_ARRAY * sizeof(int));

これらはすべて、すべてのデータを に渡しますが、theFunction()意味があるかどうかは何をするかによって異なりますtheFunction()

于 2011-01-07T22:54:32.120 に答える
0

の割り当ての部分:integers whose values can be up to 4095 using this function (that only takes unsigned charsは、大きなヒントを与えてくれるはずです。4095 符号なしは 12 ビットです。

12 ビットを 16 ビットに格納できますがshort、これはやや無駄なスペースです。16 ビットのうち 12 ビットしか使用していません。文字の変換では 1 バイト以上を扱うため、結果のエンディアンに対処する必要がある場合があります。最も簡単です。

スペースが心配な場合は、ビット フィールドまたはパックされたバイナリ構造を使用することもできます。もっと仕事。

于 2011-01-07T20:55:56.820 に答える
0

If you have to write an array of integers then just convert the array into a pointer to char then run through the array.

int main()
{
    int    data[] = { 1, 2, 3, 4 ,5 };
    size_t size   = sizeof(data)/sizeof(data[0]); // Number of integers.

    unsigned char* out = (unsigned char*)data;
    for(size_t loop =0; loop < (size * sizeof(int)); ++loop)
    {
         MyProfSuperWrite(out + loop);  // Write 1 unsigned char
    }
}

Now people have mentioned that 4096 will fit in less bits than a normal integer. Probably true. Thus you can save space and not write out the top bits of each integer. Personally I think this is not worth the effort. The extra code to write the value and processes the incoming data is not worth the savings you would get (Maybe if the data was the size of the library of congress). Rule one do as little work as possible (its easier to maintain). Rule two optimize if asked (but ask why first). You may save space but it will cost in processing time and maintenance costs.

于 2011-01-07T23:16:18.090 に答える
0

あなたが本当にやりたいことは、整数の文字列表現を取得するために sprintf を呼び出すことのようです。これは、数値型から文字列表現に変換する標準的な方法です。次のようなものから始めることができます。

char num[5]; // Room for 4095

// Array is the array of integers, and arrayLen is its length
for (i = 0; i < arrayLen; i++)
{
    sprintf (num, "%d", array[i]);

    // Call your function that expects a pointer to chars
    printfunc (num);
}
于 2011-01-07T20:40:40.903 に答える