圧縮プログラムを作成していますが、c++を使用してビットデータをバイナリファイルに書き込む必要があります。誰かが書き込みステートメント、またはアドバイス付きのWebサイトについてアドバイスできれば、私は非常に感謝します。
これが単純な質問または紛らわしい質問である場合は、お詫び申し上げます。ウェブ上で回答を見つけるのに苦労しています。
圧縮プログラムを作成していますが、c++を使用してビットデータをバイナリファイルに書き込む必要があります。誰かが書き込みステートメント、またはアドバイス付きのWebサイトについてアドバイスできれば、私は非常に感謝します。
これが単純な質問または紛らわしい質問である場合は、お詫び申し上げます。ウェブ上で回答を見つけるのに苦労しています。
unsignedcharやstd::bitset(ビットセットサイズはCHAR_BITの倍数)などのバイト全体にビットを収集してから、一度にバイト全体を書き込みます。コンピューターは「ビットを処理」しますが、特にIOの場合、利用可能な抽象化は、プログラマーとして個々のバイトを処理することです。ビット単位の操作を使用して特定のビットを切り替えることができますが、常にバイトサイズのオブジェクトを処理しています。
出力の最後に、バイト全体がない場合は、それをどのように格納するかを決定する必要があります。iostreamとstdioはどちらも、それぞれostream::writeとfwriteを使用してフォーマットされていないデータを書き込むことができます。
単一の文字またはビットセット<8>(8はCHAR_BITの最も一般的な値)の代わりに、4〜32文字以上の文字または同等のサイズのビットセットの配列など、より大きなブロックサイズを使用することを検討してください。
バイナリを書き込む場合、私が最も役立つと思ったトリックは、すべてのバイナリを単一の配列としてメモリに格納し、それをすべてハードドライブに移動することです。一度に1ビット、一度に1バイト、または一度にunsigned long longを実行することは、すべてのデータを配列に格納し、「fwrite()」の1つのインスタンスを使用して格納するほど高速ではありません。ハードドライブ。
size_t fwrite(const void * ptr、size_t size、size_t count、FILE * stream);
参照:http ://www.cplusplus.com/reference/clibrary/cstdio/fwrite/
英語で:
fwrite([格納されたデータの配列*]、[配列OBJECTのバイト単位のサイズ。unsignedchars-> 1の場合、unsigned longlongsの場合->8]、[配列内のインスタンスの数]、[FILE *])
成功の検証のために常にあなたのリターンをチェックしてください!
さらに、オブジェクトタイプをできるだけ大きくすることが最速の方法であるという議論をすることができます([unsigned long long]> [char])。「fwrite()」の背後にあるコーディングに精通していませんが、コードで使用されている自然なオブジェクトから[unsigned long long]に変換する時間は、「fwrite()」よりも書き込みと組み合わせると時間がかかると思います。 「あなたが持っているもので期限を迎えます。
ハフマン符号化を学んでいた頃、[char]と[unsignedchar]に違いがあることに気付くのに数時間かかりました。このメソッドでは、純粋なバイナリを格納するために常に符号なし変数を使用する必要があることに注意してください。
以下のクラスでは、ビットごとに書き込みと読み取りを行うことができます
class bitChar{
public:
unsigned char* c;
int shift_count;
string BITS;
bitChar()
{
shift_count = 0;
c = (unsigned char*)calloc(1, sizeof(char));
}
string readByBits(ifstream& inf)
{
string s ="";
char buffer[1];
while (inf.read (buffer, 1))
{
s += getBits(*buffer);
}
return s;
}
void setBITS(string X)
{
BITS = X;
}
int insertBits(ofstream& outf)
{
int total = 0;
while(BITS.length())
{
if(BITS[0] == '1')
*c |= 1;
*c <<= 1;
++shift_count;
++total;
BITS.erase(0, 1);
if(shift_count == 7 )
{
if(BITS.size()>0)
{
if(BITS[0] == '1')
*c |= 1;
++total;
BITS.erase(0, 1);
}
writeBits(outf);
shift_count = 0;
free(c);
c = (unsigned char*)calloc(1, sizeof(char));
}
}
if(shift_count > 0)
{
*c <<= (7 - shift_count);
writeBits(outf);
free(c);
c = (unsigned char*)calloc(1, sizeof(char));
}
outf.close();
return total;
}
string getBits(unsigned char X)
{
stringstream itoa;
for(unsigned s = 7; s > 0 ; s--)
{
itoa << ((X >> s) & 1);
}
itoa << (X&1) ;
return itoa.str();
}
void writeBits(ofstream& outf)
{
outf << *c;
}
~bitChar()
{
if(c)
free(c);
}
};
にとってexample
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;
int main()
{
ofstream outf("Sample.dat");
ifstream inf("Sample.dat");
string enCoded = "101000001010101010";
//write to file
cout << enCoded << endl ; //print 101000001010101010
bitChar bchar;
bchar.setBITS(enCoded);
bchar.insertBits(outf);
//read from file
string decoded =bchar.readByBits(inf);
cout << decoded << endl ; //print 101000001010101010000000
return 0;
}