29

私はこの文字列を持っています: "101"私はそれをテキストとしてではなくCでファイルに書きたいです:"101"そして8ビットx文字。ただし、文字列をビットとして直接使用します。ビット「1」、ビット「0」、およびビット「1」であるため、ファイルは3ビットになります。

それは可能ですか?私はウェブで検索し、これを試してみました:

char c[25] = "101";
FILE *binFile = fopen("binFile.bin", "wb");
int x = atoi(c);
fwrite(&x, sizeof(x), 1, binFile);

しかし、最後に、ファイルのバイトを確認すると、Windowsはそれが4バイトのファイルであると私に言います!そして、3ビットではありません!

可能であれば、どうすればこれを行うことができますか?どうもありがとう。

4

5 に答える 5

36

すべてのファイルシステム¹は、バイト単位でファイルを処理します(そして、最小時間で512バイトという、はるかに細かい粒度でストレージスペースを割り当てます)。3ビット長のファイルを取得する方法はありません。

あなたができる最善のことは、1バイト全体を使い切ることですが、そのビットの5つは無視してください。これを行うには(数値が常に1バイトに収まると仮定して)、入力文字列を整数型に変換します。

long l = strtol(c, 0, 2);

次に、最下位バイトを取得します。

unsigned char b = l & 0xffl;

そしてそれをファイルに書き込みます:

fwrite(&b, 1, 1, binFile);

¹まあ、すべてではないかもしれません。ビットサイズのファイルシステムを実験している研究者がどこかにいる可能性があります。わかりません。

于 2012-11-06T14:06:55.217 に答える
15

をファイルに書き込んでいるため、出力ファイルの長さは4バイトintです。ほとんどのプラットフォームでは、anのintサイズは4バイトです。

一度に1バイト未満を書き込むことはできません。

于 2012-11-06T14:07:52.270 に答える
7

あなたができることはそれをビット(3)として書き、それを1バイトまで0で埋めることです。ただし、実際に使用されているビット数(または最後のバイトからのビット数)で開始(または終了)する必要もあります。

例(最初のバイトを長さとして使用):

00000011   -> 3, meaning from the last (and only byte in this case, 
              only the first 3 bits are used)
10100000   -> 101 is the string, other 5 bits are 0, just use for padding

この場合、最初の(長さ)バイトのオーバーヘッドは50%であり、文字列が長いほど、もちろんオーバーヘッドの割合は少なくなります。

于 2012-11-06T14:08:57.923 に答える
6

あなたのアプローチに関する2つのメモ:

  1. [最新]コンピュータはメモリ内で1バイト未満を処理できないため、ディスクに1ビットを書き込むことはできません。

    また、ファイルシステムは通常、ファイルが収まるチャンク(512バイト、1Kbなど)でスペースを割り当てます。したがって、500バイトのファイルがある場合、実際には512バイトのディスク領域が失われています。

  2. atoi()文字列から2進数に変換するのではなく、整数に変換します。あなたは実際に書いています0b1100101、それは0d101です。最初に変換を行う必要があります。何かのようなもの:

    char b = 0;
    for (int i=0; c[i]!=NULL; i++) 
    {
        b = ((b<<1) | atoi(c[i]));
    }
    
于 2012-11-06T14:31:50.927 に答える
4

あなたはビット101を書いているのではなく、10進数の2進数の値101、すなわち 1100101。あなたはバイトfreadのサイズなsizeof(x)ので、ファイルのsizeof(x)長さはバイトになります。

于 2012-11-06T14:11:13.843 に答える