[ad_1]
みなさん、こんにちは。独自のデータ コンプレッサーとデコンプレッサーを作成しようとしています。ここでいくつかの投稿を見て、それらを変更しようとしましたが、問題があります。
それを圧縮するファイルのtrial.txtプログラムを作成したとしましょうが、多くの00 00 00 00を追加すると、圧縮バージョンが元のものよりも大きくなります。
だから私が欲しいのは、プログラムが圧縮および解凍されたバージョンをtxtとして保存する優れた圧縮ロジックです。 ハフマンアルゴリズムを試してみましたが、うまくいきませんでした。
私のコードは以下の通りです。 「ncurses.h」ライブラリが機能しない場合、コンパイラでエラーが発生する場合があります。「conio.h」も削除して追加できます
+++update 以下のようにコードを修正しました。問題は 1 つだけです。たとえば、解凍関数がメッセージの最後の文字を取得しません。
メッセージ: Hello World
圧縮された A0 B3 DD …
解凍: Hello World
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include <ncurses.h> #include <errno.h> void Compression(unsigned char *sizeOut, const char *Message_size) { unsigned long long Buffer = 0; char Bits = 0; while (*Message_size != 0) { Buffer |= (unsigned long long)(*Message_size++) << Bits; Bits += 7; if (Bits == 7 * 8) { while (Bits > 0) { *sizeOut++ = Buffer; Buffer >>= 8; Bits -= 8; } Bits = 0; Buffer = 0; } } while (Bits > 0) { *sizeOut++ = Buffer; Buffer >>= 8; Bits -= 8; } } void Decompression (char *Out_size, const unsigned char *Compressed_size, unsigned CompressedLength) { unsigned long long Buffer = 0; char Bits = 0; while (CompressedLength) { while (CompressedLength && Bits < 7 * 8) { Buffer |= (unsigned long long)*Compressed_size++ << Bits; Bits += 8; --CompressedLength; } while (Bits > 0) { *Out_size++ = Buffer & 0x7F; Buffer >>= 7; Bits -= 7; } Bits = 0; Buffer = 0; } } int main(void) { int letters; printf("Creator: Ceyhun Kivanc Demir, data compressor and decompressor\n\n"); FILE *file; char filename[100]=""; printf("\n\nPlease Enter the name of file: "); scanf("%99s",filename); file=fopen(filename,"r"); if(file==NULL){ printf("\n%s File not found.\n\n",filename, strerror(errno)); exit(1); } fseek(file, 0, SEEK_END); long count = ftell(file); fseek(file, 0, SEEK_SET); char Message[count]; fread(Message, strlen(Message)+1, count, file); Message[count]='\0'; unsigned CompressedSize = sizeof(Message)*7/8; unsigned char CompressedBytes[CompressedSize]; char DecompressedSize[sizeof(Message)]; printf("\nMessage: %s\n", Message); Compression(CompressedBytes, Message); printf("char number of message: %d\n", strlen(Message)); printf("\nCompressed version: "); for (int Byte = 0; Byte < CompressedSize; ++Byte) { printf("%02X ", CompressedBytes[Byte]); } printf("\n"); Decompression(DecompressedSize, CompressedBytes, CompressedSize); DecompressedSize[sizeof(Message)] = 0; printf("\nDecompressed version: %s\n", DecompressedSize); printf("char number of message: %d\n", strlen(DecompressedSize)); if (strcmp(Message, DecompressedSize) == 0) { printf("\nCompression done.\n"); } else { printf("\nCompression crushed!\n"); } fclose(file); return 0; }
私が試したこと:
hufman アルゴリズム、ファイル保存、圧縮、解凍
解決策 1
これを見てください:
int count; /* assign a value to count */ char Message[count]; /* creates a buffer of size count */ /* ... a bit later */ unsigned CompressedSize = sizeof(Message)*7/8;
実行時に決定されるサイズでスタック上に配列を作成することは、GNU 拡張機能です。 それが間違っていると言っているわけではありませんが、注意すべき点がいくつかあります。
1) もし count
が最大スタック サイズより大きい場合、既にスタックにある他の変数が破損する可能性があります。 使ったほうがいいかも malloc/free
Message 変数を作成します。
2) Message 変数のサイズは、入力ファイルのサイズに基づいて実行時に設定されます。 しかし sizeof
演算子はで計算されます コンパイル 時間。 コンパイル時には配列のサイズがわからないため、 sizeof(Message)
に評価されます sizeof(char *)
. これは、CompressedSize の値が間違っていることを意味します。
3) ポータブルではありません。 おそらくclangはこれをサポートしていると思いますが、MSVCがサポートしていないことは確かです。 それは、今も後も、あなたにとって問題になるかもしれませんし、ならないかもしれません。
余談ですが、このコードは
while( (letters = fgetc(file)) != EOF) { count++; } fseek(file, 0, SEEK_SET);
で置き換えることができます
fseek(file, 0, SEEK_END); long count = ftell(file); fseek(file, 0, SEEK_SET);
この方法では、ファイル内の各バイトの読み取りに時間を費やす必要がなく、変数「文字」が不要になるため、(少量の) スペースを節約できます。
解決策 2
あなたのコードは今動いていますか?
[ad_2]
コメント