- ベストアンサー
構造体、ファイル処理のプログラム
#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は同じ文字とカウント)の各文字の文字数をカウントし、カウント結果をソートして、たくさんカウントされたものから順に文字を表示する。 というプログラムなのですが、セグメントエラーとでてしまいます。どこが悪いのか指摘してください。
- みんなの回答 (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; } 以上。
その他の回答 (1)
- Tacosan
- ベストアンサー率23% (3656/15482)
少なくとも, while (rv[i] != EOF) は変. その前が「EOF でなかったら rv[i] に入れる」という感じになっているので, EOF が入っていると期待することはできない. それとは別に, isupper とか tolower を使えよと言いたいけど, そこは本質的な問題じゃないのでとりあえず置いておく. おお, よく見たら c=rv[i]; なんてのもあるなぁ. 意味がわからん.
お礼
ご指摘ありがとうございます。 なるほど確かにその通りです。 isupper とか tolowerは私の知識不足でした。
お礼
無事上手くできました。 ホントここまでしてくれてとても感謝しています。 ありがとうございます。