入力用ファイルの情報を読み込み,このファイルの情報をランレングス符号化を用いて符号化し,結果を出力用ファイル名に出力するCプログラムを作成しようとしているのですが正確に符号化することができません(情報の個数が正しくカウントできない)どうすればよいのかわからないので教えていただけないでしょうか。
#include <stdio.h>
main(void){
FILE *fi;
FILE *fo;
int ccs;
unsigned char c=1;
char a,b,d;
fi=fopen("files99.txt","rb");
fo=fopen("files100.dat","wb");
fread(&a,sizeof(a),1,fi);
ccs=fread(&d,sizeof(d),1,fi);
while(ccs>0){
fread(&b,sizeof(b),1,fi);
if(a==b){
c=c+1;
} else {
fwrite(&a,sizeof(a),1,fo);
fwrite(&c,sizeof(c),1,fo);
a=b;
c=1;
}
ccs=fread(&d,sizeof(d),1,fi);
}
これでは入力用ファイルをfiles99.txtとし
出力用ファイルをfiles100.datとしています。
どこを改善すればよいのか手持ちの資料や学校の図書館を全て調べてもわかりませんでした。
どうかよろしくお願いします。
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
★アドバイス
・最初『ccs=fread(&d,sizeof(d),1,fi);』を読み込んでいるが、
a=d が同じか、違うかをチェックしていない。
・ループ中で
『fread(&b,sizeof(b),1,fi);』を読み込んだ後に、また
『fread(&d,sizeof(d),1,fi);』を読み込んでいる。
ここでもb=dが同じか、違うのかをチェックしていない。
よって正しく符号化が出来ないのです。
・直すとしたら次のステップになります。
(1)最初に1文字(a)を読み込む
(2)do-while でループを構成
(3)『fread(&b,sizeof(b),1,fi);』を削除
(4)if(a==b){ … }の処理を記述
(5)do-while の直前で次の1文字(b)を読み込む
(6)do-while の条件式で fread の戻り値が 0 なら終了
とします。
・でも1文字取得する場合は fgetc を使えば分かりやすくなりますよ。
fgetc ならばファイルの終わりは EOF が返されます。
あと c カウンタは unsigned char 型ですので同じ文字が 256 以上の場合は
c カウンタが 0 にリセットされます。ここの部分を考慮して改良してください。
前回のサンプルにある『else if ( n >= 255 ){』でもファイルに書き出しています。
c カウンタが 255 になったら文字コード、連続する数をファイルに書き出しましょう。
・以上。まずは fread から fgetc に書き直してみる。この方が分かりやすいと思うよ。
No.2
- 回答日時:
※訂正。
>(3)どうして ccs の値でループして処理をしているのですか?
> files99.txt ファイルにNULコードが含まれているの?
> ここがおかしい気がします。
↑
freadの戻り値ならおかしくないね。
・失礼しました。
この回答への補足
ccsのループはfreadの返り値が0のときになれば最後まで読み込んだことになるので終了するという意味です。
プログラムを最後まで書き込んでいませんでした。
fclose(fo);
fclose(fi);
return 0;
}
が続きますすみませんでした。
情報の個数をカウントするにはどこを改善すればよいでしょうか?
No.1
- 回答日時:
★アドバイス
(1)念のために fopen の戻り値をチェックして下さい。
(2)fread よりも fgetc で1文字読み込むほうが分かりやすい気がします。
(3)どうして ccs の値でループして処理をしているのですか?
files99.txt ファイルにNULコードが含まれているの?
ここがおかしい気がします。
>どこを改善すればよいのか手持ちの資料や学校の図書館を全て調べてもわかりませんでした。
↑
手持ちの資料がない。
学校の図書館でも分からない。
それならネットで検索をして下さい。
見つかりますよ。
例えば
http://ja.wikipedia.org/wiki/%E9%80%A3%E9%95%B7% …→『連長圧縮』
などを参考にして下さい。
これは『ランレングス圧縮』の基本です。
サンプル:
int n = 1; // ランレングス(文字カウンタ)
int b; // 1つ前の文字コード
int c; // 今現在の文字コード
for ( b = -1 ; (c = fgetc(fi)) != EOF ; b = c ){
if ( c != b ){
if ( b != -1 ){
fputc( b, fo );
fputc( n, fo );
n = 1;
}
}
else if ( n >= 255 ){
fputc( b, fo );
fputc( n, fo );
n = 1;
}
else{
n++;
}
}
fputc( b, fo );
fputc( n, fo );
以上。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# #include <stdio.h>int main(void) { int buf[100] = 6 2022/11/01 22:45
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語について教えて欲しいです。 ファイルの中身をコピーするプログラムを作ってます aというファイル 7 2022/11/03 19:21
- C言語・C++・C# 100バイトのバイナリファイルを読み込んで別のファイルに書き込みたいのですが、型をどうすればいいのか 1 2022/11/03 17:11
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- その他(プログラミング・Web制作) python OpenPyXLを使って出力結果をエクセルに書き込み 2 2022/06/04 19:46
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAでPowerPointからExcelにデ...
-
access vbaでCSVファイルを文...
-
unicode文字列(日本語)のファイ...
-
VBAで新しい日付順にファイルを...
-
fortranでのcsvファイルを出力...
-
ある文字列を含む行の抽出
-
複数行の文字列を変数として使...
-
特定フォルダ内のテキストファ...
-
Excel.VBA テキストファイルを...
-
ソースコードの差分がある行番...
-
BCPユーティリティの使用法_...
-
テキストファイルを直接置換す...
-
フォルダ比較の結果をテキスト...
-
iniファイルとの比較(iniファイ...
-
コマンドプロンプトの「%1」と...
-
コマンドプロンプトのエラーに...
-
画像・動画データを日付毎のフ...
-
バッチでテキストファイルから...
-
大量のフォルダからひとつのフ...
-
Thunderbirdで社内共有フォルダ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAでPowerPointからExcelにデ...
-
複数行の文字列を変数として使...
-
特定フォルダ内のテキストファ...
-
VBAで新しい日付順にファイルを...
-
VB6側からテキストファイルをク...
-
テキストファイルを直接置換す...
-
RandomとBinaryモードの違い
-
Excel.VBA テキストファイルを...
-
バッチでiniファイルの編集
-
fortranでのcsvファイルを出力...
-
ある文字列を含む行の抽出
-
テキストファイルの行頭に文字...
-
access vbaでCSVファイルを文...
-
C#でのファイル編集と上書き保...
-
BCPユーティリティの使用法_...
-
unicode文字列(日本語)のファイ...
-
c言語の問題です
-
VBSを用いてIPアドレスを取得し...
-
VBAで任意のフォルダ内のファイ...
-
excelにテキストファイルの指定...
おすすめ情報