• ベストアンサー

構造体、ファイル処理のプログラム

#include<stdio.h> typedef struct stat {   char alph;   int count; }Stat; int main(int argc, char *argv[]){   FILE *fp;   int i=0,j=0;   char rv[1000],c;   Stat tmp,al[26];   for(i=0;i<26;i++){   al[i].alph='a'+i;   al[i].count=0;  } if(argc==2){ fp = fopen(argv[1],"r");  if(fp==NULL){     printf("not found.\n"); exit(1); } } else{ printf("Can not open.\n"); } while((c=fgetc(fp))!=EOF){ c=rv[i]; if( 'A'<=rv[i] && rv[i]<='Z'){ rv[i] = rv[i] + ('a' - 'A'); } i++; } i=0; while(rv[i]!=EOF){ for(j=0;j<26;j++){ if(rv[i] == al[j].alph){ break; }  } al[j].count++; i++; } for(i=0;i<26;i++){ for(j=i+1;j<26;j++){ if(al[i].count > al[j].count){ tmp =al[i]; al[i]=al[j]; al[j]=tmp; }  }  } for(i=0;i<26;i++){ printf("%s %d\n",al[i].alph,al[i].count); } fclose(fp); return 0; } コマンドラインで指定したファイルを読み、その中に出てくるアルファベット(a-z, A-Z)(aとAは同じ文字とカウント)の各文字の文字数をカウントし、カウント結果をソートして、たくさんカウントされたものから順に文字を表示する。 というプログラムなのですが、セグメントエラーとでてしまいます。どこが悪いのか指摘してください。

質問者が選んだベストアンサー

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

★アドバイス ・ざっと見た限りでは fgetc() のループと  al[j].count のカウント部のループがおかしい。 ・これ以上ソースをチェックするのが面倒なので同じものを作ってみた。  下のサンプルを参考に自分のソースを修正してみて下さい。  解説しないので読み取ってね。 サンプル: #include <ctype.h> #include <stdio.h> // 構造体 typedef struct stat {  char alpha;  int count; } Stat; // メイン関数 int main( int argc, char *argv[] ) {  // 宣言  Stat stat[ 26 ];  Stat temp[ 1 ];  FILE *fp;  int i, c;  int j0, j1;    // 初期化  for ( i = 0, c = 'a' ; c <= 'z' ; c++, i++ ){   stat[ i ].alpha = (char)c;   stat[ i ].count = 0;  }  // 引数チェック  if ( argc != 2 ){   printf( "Can not open.\n" );   return 1;  }  if ( (fp = fopen(argv[1],"r")) == NULL ){   printf( "not found.\n" );   return 2;  }  // 読み込み  while ( (c = fgetc(fp)) != EOF ){   if ( isupper(c) ){    stat[ c - 'A' ].count++;   }   else if ( islower(c) ){    stat[ c - 'a' ].count++;   }  }  fclose( fp );    // バブルソート(降順)  for ( i = 25 ; i >= 0 ; i-- ){   for ( j1 = 1, j0 = 0 ; j0 < i ; j0++, j1++ ){    if ( stat[j0].count < stat[j1].count ){ ←『降順』なので符号が逆。     temp[ 0 ] = stat[ j0 ];     stat[ j0 ] = stat[ j1 ];     stat[ j1 ] = temp[ 0 ];    }   }  }  // 結果表示  for ( i = 0 ; i < 26 ; i++ ){   printf( "%c %d\n", stat[i].alpha, stat[i].count );  }  return 0; } 以上。

blade3322
質問者

お礼

無事上手くできました。 ホントここまでしてくれてとても感謝しています。 ありがとうございます。

その他の回答 (1)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

少なくとも, while (rv[i] != EOF) は変. その前が「EOF でなかったら rv[i] に入れる」という感じになっているので, EOF が入っていると期待することはできない. それとは別に, isupper とか tolower を使えよと言いたいけど, そこは本質的な問題じゃないのでとりあえず置いておく. おお, よく見たら c=rv[i]; なんてのもあるなぁ. 意味がわからん.

blade3322
質問者

お礼

ご指摘ありがとうございます。 なるほど確かにその通りです。 isupper とか tolowerは私の知識不足でした。

関連するQ&A

専門家に質問してみよう