11

zlib.h deflateおよびinflate関数を実装して、char配列(ファイルではない)を圧縮および解凍しようとしています。

次の構文が正しいかどうか知りたいですか?私は何かが欠けているか、何かが間違って定義されていますか?

char a[50] = "Hello World!";
char b[50];
char c[50];

// deflate
// zlib struct
z_stream defstream;
defstream.zalloc = Z_NULL;
defstream.zfree = Z_NULL;
defstream.opaque = Z_NULL;
defstream.avail_in = (uInt)sizeof(a); // size of input
defstream.next_in = (Bytef *)a; // input char array
defstream.avail_out = (uInt)sizeof(b); // size of output
defstream.next_out = (Bytef *)b; // output char array

deflateInit(&defstream, Z_DEFAULT_COMPRESSION);
deflate(&defstream, Z_FINISH);
deflateEnd(&defstream);

printf("Deflate:\n%lu\n%s\n", strlen(b), b);

// inflate
// zlib struct
z_stream infstream;
infstream.zalloc = Z_NULL;
infstream.zfree = Z_NULL;
infstream.opaque = Z_NULL;
infstream.avail_in = (uInt)sizeof(b); // size of input
infstream.next_in = (Bytef *)b; // input char array
infstream.avail_out = (uInt)sizeof(c); // size of output
infstream.next_out = (Bytef *)c; // output char array

inflateInit(&infstream);
inflate(&infstream, Z_NO_FLUSH);
inflateEnd(&infstream);

printf("Inflate:\n%lu\n%s\n", strlen(c), c);
4

3 に答える 3

31

zlibには、使用できる単純な膨張/収縮関数がすでにあります。

char a[50] = "Hello, world!";
char b[50];
char c[50];

uLong ucompSize = strlen(a)+1; // "Hello, world!" + NULL delimiter.
uLong compSize = compressBound(ucompSize);

// Deflate
compress((Bytef *)b, &compSize, (Bytef *)a, ucompSize);

// Inflate
uncompress((Bytef *)c, &ucompSize, (Bytef *)b, compSize);

疑わしい場合は、zlibのマニュアルを確認してください。私のコードはくだらない、ごめんなさい= /

于 2012-05-19T08:07:12.277 に答える
7

このようにデフレートされた出力をprintfすることはできません。nullで終了するわけではありません。あなたもそれを伸ばすことはできません。

入力は文字列であるため、おそらくnullターミネータを含む文字列の内容のみを渡したいと思うでしょう。したがって、avail_inをstrlen(a)+1に設定します。

deflateを呼び出した後、next_outフィールドとavail_outフィールドを調べて、出力バッファーに書き込まれたデータの量を確認する必要があります。

deflate呼び出しの下にあるここのドキュメントを参照してください。

これが変更されたコードです。文字列ではないものを圧縮する場合は、これを変更する必要があります。また、文字列を使用する場合は、ゼロを終了せずに圧縮し、解凍後に追加し直すことができます。

char a[50] = "Hello World!";
char b[50];
char c[50];

// deflate
// zlib struct
z_stream defstream;
defstream.zalloc = Z_NULL;
defstream.zfree = Z_NULL;
defstream.opaque = Z_NULL;
defstream.avail_in = (uInt)strlen(a)+1; // size of input, string + terminator
defstream.next_in = (Bytef *)a; // input char array
defstream.avail_out = (uInt)sizeof(b); // size of output
defstream.next_out = (Bytef *)b; // output char array

deflateInit(&defstream, Z_DEFAULT_COMPRESSION);
deflate(&defstream, Z_FINISH);
deflateEnd(&defstream);

// This is one way of getting the size of the output
printf("Deflated size is: %lu\n", (char*)defstream.next_out - b);

// inflate
// zlib struct
z_stream infstream;
infstream.zalloc = Z_NULL;
infstream.zfree = Z_NULL;
infstream.opaque = Z_NULL;
infstream.avail_in = (uInt)((char*)defstream.next_out - b); // size of input
infstream.next_in = (Bytef *)b; // input char array
infstream.avail_out = (uInt)sizeof(c); // size of output
infstream.next_out = (Bytef *)c; // output char array

inflateInit(&infstream);
inflate(&infstream, Z_NO_FLUSH);
inflateEnd(&infstream);

printf("Inflate:\n%lu\n%s\n", strlen(c), c);
于 2011-09-24T16:41:19.633 に答える
3

zpipeの例(http://zlib.net/zpipe.c)はそれをほぼカバーしており、ファイルops(fプレフィックス関数)を削除するだけで、メモリ内のバッファを置き換えるinだけoutで十分かもしれません。in使用状況に応じて、バッファをそのまま交換または保持するだけです。サイズが不明なチャンクを計画している場合は、任意のサイズのデータ​​の解凍を考慮して、出力バッファーのサイズを変更可能にする必要があることに注意してください。

于 2011-09-24T18:53:49.603 に答える