【C言語】第10章第4回:ファイル圧縮ツールの作成
C言語を使って、シンプルなファイル圧縮ツールを作成します。本記事では、基本的なデータ圧縮アルゴリズムとその実装方法を学びます。
0. 記事の概要
この記事を読むメリット
- データ圧縮の基本理解:簡単な圧縮アルゴリズムの実装を通じて、圧縮の仕組みを学べます。
- ファイル操作スキルの向上:ファイルの読み書きとデータ操作を組み合わせた応用力を養います。
- プログラムの応用可能性:圧縮アルゴリズムを拡張して、より高度なツールを開発できます。
この記事で学べること
- シンプルなデータ圧縮アルゴリズム
- ファイルの読み書き処理
- アルゴリズムの効率性を考慮したプログラム設計
1. ファイル圧縮ツールの基本設計
1.1 圧縮ツールの機能
このツールでは、以下の基本機能を実装します。
- テキストファイルの圧縮
- 圧縮ファイルの解凍
- アルゴリズムの効率化(ランレングス圧縮法を使用)
1.2 ランレングス圧縮法とは?
ランレングス圧縮法(Run-Length Encoding: RLE)は、連続する同じデータをそのデータの値と繰り返し回数に置き換える手法です。
例:
入力: AAAABBBCCDAA
出力: A4B3C2D1A2
1.3 必要なプログラム構造
プログラムは以下の主要部分で構成されます。
- ファイルの読み込み
- データの圧縮処理
- 圧縮結果の保存と解凍処理
2. コード例と詳細解説
2.1 基本コード例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 圧縮処理
void compressFile(const char *inputFile, const char *outputFile) {
FILE *in = fopen(inputFile, "r");
FILE *out = fopen(outputFile, "w");
if (!in || !out) {
printf("ファイルを開けませんでした。\\n");
return;
}
char currentChar, prevChar = '\0';
int count = 0;
while ((currentChar = fgetc(in)) != EOF) {
if (currentChar == prevChar) {
count++;
} else {
if (count > 0) {
fprintf(out, "%c%d", prevChar, count);
}
prevChar = currentChar;
count = 1;
}
}
if (count > 0) {
fprintf(out, "%c%d", prevChar, count);
}
fclose(in);
fclose(out);
printf("圧縮が完了しました。\\n");
}
// 解凍処理
void decompressFile(const char *inputFile, const char *outputFile) {
FILE *in = fopen(inputFile, "r");
FILE *out = fopen(outputFile, "w");
if (!in || !out) {
printf("ファイルを開けませんでした。\\n");
return;
}
char ch;
int count;
while (fscanf(in, "%c%d", &ch, &count) == 2) {
for (int i = 0; i < count; i++) {
fputc(ch, out);
}
}
fclose(in);
fclose(out);
printf("解凍が完了しました。\\n");
}
int main() {
char inputFile[100], outputFile[100];
int choice;
printf("ファイル圧縮ツールへようこそ!\\n");
printf("1. 圧縮\\n");
printf("2. 解凍\\n");
printf("選択してください: ");
scanf("%d", &choice);
printf("入力ファイル名を入力してください: ");
scanf("%s", inputFile);
printf("出力ファイル名を入力してください: ");
scanf("%s", outputFile);
if (choice == 1) {
compressFile(inputFile, outputFile);
} else if (choice == 2) {
decompressFile(inputFile, outputFile);
} else {
printf("無効な選択です。\\n");
}
return 0;
}
動作解説
- 圧縮処理:`compressFile`関数でランレングス圧縮を実行し、結果をファイルに保存します。
- 解凍処理:`decompressFile`関数で圧縮データを元の形式に戻します。
- ユーザーインターフェース:`scanf`でユーザーからファイル名や処理の選択を取得します。
3. 練習問題
以下の課題に挑戦して、ファイル圧縮ツールを拡張してみましょう。
- 圧縮アルゴリズムを改良して、文字列だけでなくバイナリデータにも対応できるようにしてください。
- 圧縮率を計算して、圧縮前後のサイズを表示してください。
- 圧縮データにエラーチェック機能を追加して、解凍時にデータの正確性を確認してください。
4. 練習問題の解答と解説
問2の解答例
// 圧縮率の計算
void calculateCompressionRatio(const char *inputFile, const char *outputFile) {
FILE *in = fopen(inputFile, "r");
FILE *out = fopen(outputFile, "r");
if (!in || !out) {
printf("ファイルを開けませんでした。\\n");
return;
}
fseek(in, 0, SEEK_END);
long inputSize = ftell(in);
fclose(in);
fseek(out, 0, SEEK_END);
long outputSize = ftell(out);
fclose(out);
printf("圧縮前のサイズ: %ld bytes\\n", inputSize);
printf("圧縮後のサイズ: %ld bytes\\n", outputSize);
printf("圧縮率: %.2f%%\\n", ((double)(inputSize - outputSize) / inputSize) * 100);
}
このプログラムでは、圧縮前後のサイズを計算し、圧縮率を出力します。
5. まとめ
本記事では、C言語を用いたファイル圧縮ツールの基本的な作成方法を解説しました。さらに高度なアルゴリズムを導入して、実用的なツールに進化させてみましょう。