• 締切済み

ランレングス符号化を用いた符号化プログラムについて教えてください

入力用ファイルの情報を読み込み,このファイルの情報をランレングス符号化を用いて符号化し,結果を出力用ファイル名に出力する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としています。 どこを改善すればよいのか手持ちの資料や学校の図書館を全て調べてもわかりませんでした。 どうかよろしくお願いします。

みんなの回答

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答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 に書き直してみる。この方が分かりやすいと思うよ。

全文を見る
すると、全ての回答が全文表示されます。
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

※訂正。 >(3)どうして ccs の値でループして処理をしているのですか? > files99.txt ファイルにNULコードが含まれているの? > ここがおかしい気がします。  ↑  freadの戻り値ならおかしくないね。 ・失礼しました。

meooo
質問者

補足

ccsのループはfreadの返り値が0のときになれば最後まで読み込んだことになるので終了するという意味です。 プログラムを最後まで書き込んでいませんでした。 fclose(fo); fclose(fi); return 0; } が続きますすみませんでした。 情報の個数をカウントするにはどこを改善すればよいでしょうか?

全文を見る
すると、全ての回答が全文表示されます。
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.1

★アドバイス  (1)念のために fopen の戻り値をチェックして下さい。  (2)fread よりも fgetc で1文字読み込むほうが分かりやすい気がします。  (3)どうして ccs の値でループして処理をしているのですか?   files99.txt ファイルにNULコードが含まれているの?   ここがおかしい気がします。 >どこを改善すればよいのか手持ちの資料や学校の図書館を全て調べてもわかりませんでした。  ↑  手持ちの資料がない。  学校の図書館でも分からない。  それならネットで検索をして下さい。  見つかりますよ。  例えば  http://ja.wikipedia.org/wiki/%E9%80%A3%E9%95%B7%E5%9C%A7%E7%B8%AE→『連長圧縮』  などを参考にして下さい。  これは『ランレングス圧縮』の基本です。 サンプル: 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

  • ハフマン符号のプログラム

     以下の問題に回答できる方,いらっしゃいましたらソースファイルと実行結果を送ってください。  ファァイル(記号列)を読み込んで,ハフマン符号によりファイルを圧縮するプログラム(C言語)を作成する(プログラムは,圧縮を行うものと,解凍を行うものの2つ作る)。また,いくつか適当なファイルに対して,圧縮を行い圧縮率を測定する。 (1)圧縮プログラムについて  圧縮のステップ  (a)入力ファイルを読み込み各記号の出現頻度をカウントする。  (b)得られた出現頻度を使って各符号のハフマン符号を生成する。  (c)各符号の出現頻度を出力ファイルに書き出す。  (d)もう一度入力ファイルを読み込みながら各符号をハフマン符号で置き換え    て出力ファイルに出力する。圧縮ファイルの形式は次のようになる。   0x00の  0x01の … 0xffの 先頭文字の 2文字目の … 終端文字の   出現頻度 出現頻度 出現頻度 符号語   符号語    符号語    (c)で書きこむ部分      (d)で書きこむ部分 (2)解凍プログラムについて  解凍のステップ  (a)各符号の出現頻度を圧縮ファイルから読み込む。  (b)得られた出現頻度を使って各符号のハフマン符号を生成する。  (c)圧縮ファイルの符号語を読み込みながら各符号のハフマン符号と比較しも    し一致したらその記号を解凍ファイルに出力する。  (d)(c)をファイルの終わりもしくは出現頻度をすべて足し合わせた記号数分処   理するまで繰り返す。  関数について  関数get_bit  ファイルから1bit読み込んで戻り値として返す。  (ファイルポインタはグローバル変数で用意する)  関数put_bit  引数として0,または1を渡すと1bitずつファイルに書き込む。  (ファイルポインタはグローバル変数で用意する)

  • fread処理がうまくいかない!!

    バイナリエディタでfwriteで書き込んだデータは確認できたのですがfread後のデータがきちんと表示されません。 どうしてでしょうか? #include <stdio.h> void main(void) { char i[] = {'a','b'}; char j[2]; FILE *fpbin; fpbin = fopen("data","wb+"); fwrite(&i,sizeof(char),2,fpbin); fpbin = fopen("data","rb"); fread(&j,sizeof(char),2,fpbin); printf("j = %c\n", j[0]); fclose(fpbin); }

  • バイナリで書き込みましたがエラーが出る。原因は?

    拡張子を.wavとしてあるa.wavというファイルがあります。 fopenとfread関数を用いて以下のように読込み、 fp = fopen("a.wav","rb"); fread(data[0],4,1,fp); fopenとfwriteを用いてb.wavファイルに以下のように書き込みました。 fa= fopen("b.wav","wb"); fwrite(data[0],4,1,fa); 書き込んだb.wavファイルですが、 バイナリエディタStirlingでa.wavとb.wavファイルの中身を比較したら中身は同じでした。 しかし、a.wavファイルでは音が出力されるのに、b.wavファイルでは音が出力されずエラーが出ます。 この原因はいったいなんでしょうか? 原因がわかる方がいましたら教えていただけないでしょうか? よろしくお願いいたします。

  • Cでバイナリデータを変換

    今持っているバイナリファイルfile1.x86をテキストファイルfile1.txtに変換したいんですけどうまくいきません。fopenとfreadでバイナリファイルを読み込むところまで入っていると思うんですけど、テキストファイルとして書き出すことができません。 #include <stdio.h> main() { short a[32000]; FILE *infile, *outfile; infile = fopen("iroha.x86", "r"); outfile = fopen("iroha.dat", "w+"); fread( a, sizeof(short), 32000, infile ); fwrite( a, sizeof(short), 32000, outfile ); fclose(infile); fclose(outfile); } これだとそのまんま出力されるんです。当たり前なんですけど... どこをどう変えればいいか教えてください。 よろしくお願いします。

  • ハフマン符号化について

    ハフマン符号化についてですが、圧縮のためであるので、 ハフマン符号化を行いなさいといわれた場合において、 木構造の1と0の取り方はどんなものでも良いのでしょうか? 生起確率が A:0.12 B:0.12 C:0.28 D:0.48 であった場合、 添付画像の青い文字のように符号化を行い、 A:000 B:001 C:01 D:1 としても、赤い文字のように符号化を行い、 A:111 B:110 C:10 D:0 としても、どちらでもハフマン符号化としては正解なのでしょうか? また、0と1を階層ごとにランダムにとっても問題ないのでしょうか?

  • freadとfwrite

     C言語初心者です。 fopenでテキストファイルで読み込んで,freadやfwriteなどは使っていいのでしょうか? 入門書などでは、freadやwriteはバイナリファイルでしか使っていないので疑問になりました。

  • プログラム(C)

    #include <stdio.h> #include <stdlib.h> #define FNAME "smp.bmp" #define WSIZE 256 #define HSIZE 256 #define BSIZE 1024 int main(void) { struct BMPFILEHEADER { ・   ・ }; struct BMPINFOHEADER { ・   ・ }; unsigned char img[HSIZE][WSIZE][3]; unsigned char buf[BSIZE]; struct BMPFILEHEADER lpHead; struct BMPINFOHEADER lpInfo; FILE *fp; int i; int j; int k; fp = fopen(FNAME,"rb"); if (fp==NULL) { printf("ファイルをオープンできません\n"); return 0; } fread(&lpHead.bfType, sizeof(unsigned short),1,fp); fread(&lpHead.bfSize, sizeof(unsigned int),1,fp); fread(&lpHead.bfReserved1, sizeof(unsigned short),1,fp); fread(&lpHead.bfReserved2, sizeof(unsigned short),1,fp); fread(&lpHead.bf0ffBits, sizeof(unsigned int),1,fp); fread(&lpInfo, sizeof(struct BMPINFOHEADER),1,fp); for(i=0;i<HSIZE;i++) { fread(buf,sizeof(unsigned char),WSIZE*3,fp); for(j=0;j<WSIZE;j++) { for(k=0;k<3;k++) { img[HSIZE-1-i][j][k]=buf[j*3+k]; } } } fclose; return 0; } このプログラムはBMP画像を読み込むプログラムなんですが このプログラムに画素値を出力するプログラムにしたいのですがうまくできません。 結果は(真っ白な画像の時)255255255・・・255255と出力したいのです。白黒画像なのでR=G=Bで1画素値は255だけでいいのですが。どうしても255255255や25500などとでてしまいます。 アドバイスお願いします。(800字までなので構造体の宣言は抜いてしましました) 。

  • ファイルコピープログラムについて

    まだC言語とか始めたばかりであまりよく分からないのですが、 今、ドラッグしたファイルをデスクトップにコピーするプログラムを作成してるのですが、少し困ったことになりました・・・・ 一応ファイルのコピーをデスクトップに作成はできるのですが、 何故か、作成されたファイルのサイズが2バイト程大きくなります・・・。 ファイルサイズを変えずにコピーする方法が分かりません・・・ ソースを張っておきますので、誰か解決策を教えていただけないでしょうか? #include <stdio.h> #include <windows.h> int main(int argc,char *argv[]) { FILE *fp,*copy; int buf; if(argc>1){ rename(argv[1],"DATA.bin"); fp=fopen("DATA.bin","rb"); copy=fopen("c:/xxx/yyy/Desktop/COPY.bin","wb"); while(1){ fread(&buf,sizeof(buf),1,fp); fwrite(&buf,sizeof(buf),1,copy); if(feof(fp)){ puts("OK"); fclose(fp); fclose(copy); rename("DATA.bin",argv[1]); rename("COPY.bin",argv[1]); exit(1); } } } return 0; }

  • 【C言語】コマンドライン引数の標準入出力

    【C言語】コマンドライン引数の標準入出力 コマンドライン引数で、ファイル名を3つ渡します。-aの次のコマンドライン引数が、出力ファイル名です。 <<例>> ・実行モジュール -a 出力ファイル名 -b ファイル名 -c ファイル名 ・実行モジュール -c ファイル名 -a 出力ファイル名 -b ファイル名 もし出力ファイルが指定されなかった場合に、標準入出力を使いたいのですが、どうしたらいいかわかりません。 下記がソースの一部です。これをどう改造したらよいでしょうか。 分かる方いらっしゃいましたらご回答いただけると幸いです。 宜しくお願いします。 //出力ファイルを取得、書き込みモードでオープン for(j=1;j<argc-1;j++){ if(strcmp(argv[j],"-o")==0){ if((fo = fopen(argv[j+1],"w"))==NULL){ printf("open error!!\n"); exit(1); } } } while(fgets(buf,sizeof(buf),fp)!= NULL){ if(strstr(buf,"keyword")!= NULL){ //出力ファイルに出力 fprintf(fo,"%d:%s",line,buf); } }

  • WINDOW CE でファイルの作成

    WINDOW CE用のプログラムを書いているのですがファイルの作成、読み込み、書き込みなど、どうしたらよいのか分かりません。普通にfopen,fclose,fread,fwriteなどを使えないとなると、どうしたら良いのでしょうか?? 出来るだけ具体的に教えてください。よろしくお願いします。