• ベストアンサー

文字カウンタ

英語の文章中で、二文字単位で読み取って、その文字列の数を出力しようと思っています。 例 hello hey you → he:2 ll:1 o :1 y :1 yo:1 u :1 解析に用いるのは、C言語でなくても、エクセルでもUNIXコマンドでも構いませんが、とりあえず、文字をカウントしたいです。 C言語での文字カウンタを作ってみたのですが、一文字単位で読みとるものしか作れませんでした。 #include <stdio.h> #include <ctype.h> int main( void ) { int ch, i; int alpcnt[26] = {0}; printf( "文字を入力\n" ); while ( ( ch = getchar( ) ) != EOF ) { if ( isupper( ch ) != 0 ) { alpcnt[ch-'A']++; } else if ( islower( ch ) != 0 ) { alpcnt[ch-'a']++; } } for ( i = 0;i < 26; i++ ) { printf( "%c : %3d個入力\t\t", 'a'+i, alpcnt[i] ); if ( i%3 == 2 ) putchar( '\n' ); } return 0; } これを少し改造するだけで作れますでしょうか? 宜しくお願いします。

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

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

なんでもいいということなのでPerlで while($line=<>){ chomp $line; #改行は捨てる $line .=" " if((length $line) % 2 == 1); #1文字余る時は空白を1つ付与する @list=split /(..)/, $line; #2文字で分ける? foreach $key (@list){ $count{$key}++ if $key ne "";#空文字以外を数える } } foreach $key (sort keys %count){#ソートして出力 print "$key:$count{$key}\n"; } __END__ hello hey you hey you what your name

Hankusu
質問者

お礼

ご回答ありがとうございました。

その他の回答 (1)

  • anmochi
  • ベストアンサー率65% (1332/2045)
回答No.1

 2文字単位にカウントするなら、カウンタは2次元の配列じゃないといけないんじゃないかな。C言語では配列の配列になる。 int alpcnt[26][26];  さらに、半角スペースも入れるなら26個じゃ足りない。面倒だし7F×7Fのマトリックスにしたらどうだろう。コントロール文字の分が不要なら5F×5Fでも良いけど。 int alpcnt[0x80][0x80]; で、こんな形にするのは訳がある。メインルーチンは面倒なので2文字目を入れないとカウントしないようにする。 while(1) { if((ch1 = getchar()) == EOF) break; if((ch2 = getchar()) == EOF) break; alpcnt[ch1][ch2]++; /* 文字のASCIIをキーとしてそのままカウント */ }  後は必要な分だけを出力してあげれば良い。とりあえず全部出力するとこんな感じ。これは、途中の表示できない文字も全部出すので、このままの利用は控えるように。 for(y = 0x20; y <= 0x7f; y++) { for(x = 0x20; x <= 0x7f; x++) { printf("%c%c is %d\n", x, y, alpcnt[x][y]); } }  また、君が作っている通り、大文字と小文字を一緒にするなら出力の段階で足し合わせてあげると良い。例えば[0x62][0x62]と[0x42][0x42]をたち合わせて表示するとか。

Hankusu
質問者

お礼

ご回答ありがとうございます。 配列を使えば、2文字単位で処理できますけど、画面に出力するときに、全部表示されてしまうんですよね。そこがまた難しいです。。

関連するQ&A

  • C言語の質問です

    下記のプログラムはテキストファイルを読み込み、AからZまでの文字(小文字、大文字は区別しない)がそれぞれ何回 現れたかを数えるプログラムです。 #include <stdio.h> #include <stdlib.h> #include <ctype.h> int count[26]; int main(int argc, char *argv[]) { FILE *fp; char ch; int i; /* ファイル名の指定を調べる */ if(argc!=2) { printf("ファイル名の指定がありません\n"); exit(1); } if((fp = fopen(argv[1], "r"))==NULL) { printf("ファイルを開くことができません\n"); exit(1); } while((ch=fgetc(fp))!=EOF) { ch = toupper(ch); if(ch>='A' && ch<='Z') count[ch-'A']++; } for(i=0; i<26; i++) printf("%c は %d 回出現\n", i+'A', count[i]); fclose(fp); return 0; } 1)int count[26]; で、なぜ26なのかが分かりません。 2)count[ch-'A']++; はどういう動作をするのか詳しく教えてほしいです。 3)よって、for文がどういう動作で表示しているのかが分かりません。 未熟者の私ですが、どなたか教えていただけないでしょうか?

  • これのどこがおかしいのでしょうか?

    文字を読み取って逆の順序表示するというのを作っているんですが、 コンパイルして実行すると、文字入力できずに終了してしまいます 自分が見る限りではどこがおかしいのかわかりません>< どうすればいいのでしょうか? #include <stdio.h> #include <conio.h> int main (void) { int a; char ch[31]; printf("文字列を読み取ります。入力してください。\n"); printf("30字まで読み取ります"); for(a = 0; a == 31; a++){ ch[a] = getche(); if(ch[a] == '\r'){ a = a; break; } if(a == 30) a = a; } printf("\n"); for(;a > 0;a--) { printf("%c ",ch[a]);  }   return 0; }

  • C言語の標準関数についての質問です。

    C言語の標準関数についての質問です。 実行結果が以下のようになるようにしたいのですが・・・ char moji[]="AB$c5kDp9#s*Gz"; ←この二行は用意されている変数です。 int cnt[4]; 実行結果↓ 英大文字:4 ←cnt[0] 英小文字:5 ←cnt[1] 数字文字:2 ←cnt[2] その他:3 ←cnt[3] 使える関数は ・isdigit ・islower ・isupper です。 ↓ 自分で作ったのですがなかなかできません>< #include <stdio.h> #include <ctype.h> void main(void) { char moji[]="AB$c5kDp9#s*Gz"; int cnt[4]={0,0,0,0},flg; cnt=0; while(flg!='\0') { flg=isupper(moji[cnt]); if(flg!=0) { cnt[0]++; } flg=islower(moji[cnt]); if(flg!=0) { cnt[1]++; } flg=flgisdigit(moji[cnt]); if(flg!=0) { cnt[2]++; } else { cnt[3]++; } } printf("英大文字:%d\n",cnt[0]); printf("英小文字:%d\n",cnt[1]); printf("数字文字:%d\n",cnt[2]); printf("その他:%d\n",cnt[3]); return; } プログラムの訂正や、他にどんなプログラムがあるのか見せてもらいたいです>< ちなみに自分のはflgを立てるやり方なのですが、エラーが・・・・。

  • 文字列をa→1b→2...z→26に変換する

    文字列を上記のように変換して表示するプログラムについて #include<stdio.h> int main() {    char ch[10];    printf("小文字のアルファベットの文字列を入力\n");    scanf("%s",&ch);    int i=0,j=97;    while(ch[i]!='\0'){      for(j; j<=97+26; j++){        if(ch[i]==j){          ch[i]=j-96;          printf("%d\n",ch[i]);        }      }    i++;    }    return 0; } 一文字の場合は問題ないのですが複数になるとうまくいきません 実行例 a 1 hello 8 となってしまいます。 改善をお願いします。

  • C言語で 小文字を大文字に変えるプログラム

    C言語で小文字を大文字に変えるプログラムを造ったのですが、エラーが出てしまいます。 どこが間違っているのか教えてください。 #include<stdio.h> main() { char a[100]; scanf(%c,&a[i]); int i=0; while(i<100){ i++; if(a[i]>60){ printf("%x-20",a[i]); }else{ printf("%x",a[i]) } } }

  • 文字と数字の判定について

    c言語を学び始めたばかりの者です。 #include <stdio.h> #include <stdlib.h> #include <time.h> #include <ctype.h> main(){ printf("数当てゲームを開始します。\n"); int a,count,n,b; srand((unsigned)time(NULL)); printf("1~10の中から1つ数字を選びます。\n"); a = (rand()%10)+1; printf("選びました\n"); for(count=0;;count++){ printf("その数字はズバリ:"); scanf("%d",&n); //もし数字でなければという文にしたい!! if (?){ printf("数字を入力してください。\n"); continue; } else{ if(n<a){ printf("もっと大きな値です。\n"); printf("%d回間違えました。\n",count+1); continue; } if(n==a){ printf("正解です!!\n"); b=0; exit(0); } if(n>a){ printf("もっと小さな値です。\n"); printf("%d回間違えました。\n",count+1); continue; } } } } というプログラムなのですが数字の判定の仕方が分からなくて最初のifの条件に何をいれればいいのか分からないので分かるかたいましたら教えてもらえないでしょうか?

  • C言語 無効な例外ハンドラー ルーチン

    失礼します現在C言語を書籍にて勉強しておりますが、エラーが出てしまいすすめません正誤表などがなくこまっています現在のソースは #include <stdio.h> int str_char(const char str[], int c) { int i; for (i = 0; str[i] != '\0'; i++) if (str[i] == c) return (i); return(-1); } int main(void) { int no; char ch[10]; printf("英文字を入力してください"); scanf_s("%s", ch); no = str_char("ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz", ch[0]); if (no >= 0 && no <= 25) printf("それは英大文字の%dです\n", no + 1); else if (no >= 26 && no <= 51) printf("それは英小文字の%dです\n", no - 25); else printf("それは英文字ではありません\n"); return(0); } で、出てくるエラーメッセージは ハンドルされない例外が 0xFEFEFEFE (helloworld.exe) で発生しました: 0xC00001A5: 無効な例外ハンドラー ルーチンが検出されました。 (パラメーター: 0x00000003)。 です。 よろしくお願いします

  • 大文字を小文字に、小文字を大文字にするプログラム

    問題は、 ファイルにあるアルファベットの大文字を小文字に変換し、小文字は大文字に変換して、ファイルに保存するプログラムを作りなさい というものです。 色々考えて、 #include <stdio.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <stdlib.h> #include <unistd.h> #include <ctype.h> int main(int argc,char **argv){ int fd,flag1,flag2; int i,n; char buffer[512],x; fd = open(argv[1],O_RDWR); if(fd == -1) perror("open"); while((n = read(fd,buffer,sizeof(buffer)))>0){ x = buffer[i]; flag1 = islower(x); flag2 = isupper(x); for(i=0;i<n;++i) if(flag1 == 1){ buffer[i] = toupper(buffer[i]); }else if(flag2 == 1){ buffer[i] = tolower(buffer[i]); } write(fd,buffer,n); } close(fd); exit(0); } のようなプログラムを考えましたが、うまくいきません。 toupperのような関数を使ったのは初めてなのでよく使い方が分からずこのようなプログラムになってしまいました。 どうか正しく動くようなプログラムを教えてください。お願いします。

  • C言語文字数4つカウント

    こんにちは。大学の課題で「キーボードから入力した文字数に含まれる'h''o''g''e'の4つの文字数をカウントする関数を含むプログラムを完成させよ」という課題がありました。なかなかできず現段階では以下のようになっています。どうすれば問題文のように実行できますか? #include <stdio.h> char str_chnum(const char str[], int ch) { int count = 0; int i; for(i = 0; str[i] != '\0'; i++) { if(str[i] == ch) count++; } return(count); } int main(void) { char str[128]; int ch; printf("文字列を入力してください:"); scanf("%s", str); printf("検索する文字を入力してください:"); scanf(" %c", &ch); printf("%cは%d個ありました。\n", ch, str_chnum(str, ch)); return(0); }

  • プログラミング(じゃんけんゲーム)

    C言語をしています。 そこでわからない所がありのですが、解説お願いします。 作りたいのは、乱数を使ったジャンケン5回戦で、 一番最後に、何勝何敗何引き分けかを表示させ、 2人のうちどちらが勝ったかです。 最後の何勝何敗何引き分けかを どう書いたらいいかがわかりません。 関数のひきわたしみたいな感じでするというのはわかります。 できたところまでのプログラムが、以下のようなコードです。 #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { int a,c,i; printf("じゃんけんをしましょう。 (グー=1 チョキ=2 パー=3)\n"); for(i=i; i<=5; i++) { srand(time(NULL)); c = rand()%3+1; scanf("%d",&a); if(a==1 && c==1) printf("私もグー=1なので、あいこです。\n"); else if(a==1 && c==2) printf("私はチョキ=2なので、あなたの勝ちです。\n"); else if(a==1 && c==3) printf("私はパー=3なので、あなたの負けです。\n"); else if(a==2 && c==1) printf("私はグー=1なので、あなたの負けです。\n"); else if(a==2 && c==2) printf("私もチョキ=2なので、あいこです。\n"); else if(a==2 && c==3) printf("私はパー=3なので、あなたの勝ちです。\n"); else if(a==3 && c==1) printf("私はグー=1なので、あなたの勝ちです。\n"); else if(a==3 && c==2) printf("私はチョキ=2なので、あなたの負けです。\n"); else if(a==3 && c==3) printf("私もパー=3なので、あいこです。\n"); else printf("正しい手を入れてください。\n"); } return 0; }

専門家に質問してみよう