• ベストアンサー

数字文字の出現回数を表示するプログラム(C言語)

タイトルのようなプログラムをCで作ろうとしています。ちなみに初学者です。 たとえば 32356695 と入力すると '0' appeared 0 times. '1' appeared 0 times. '2' appeared 1 times. '3' appeared 2 times. '4' appeared 0 times. '5' appeared 2 times. '6' appeared 2 times. '7' appeared 0 times. '8' appeared 0 times. '9' appeared 1 times. と表示されるようにしたいです。そこで以下のようなプログラムを組みましたが コンパイルは成功するもexeを実行すると数字入力後エラーメッセージが出ます。 ************************************************* #include<stdio.h> #include<string.h> #include<stdlib.h> int main(void) { int i; int count[10]={0}; int length; int digit; char str[100]; printf("Please input number:"); gets(str); length = strlen(str); for(i=0;i<length;i++){ if(str[i]>='0' && str[i]<='9'){ digit = atoi(&str[i]); count[digit]++; } } for(i=0;i<=9;i++){ printf("'%d' appeared %d times.\n",i,count[i]); } return(0); } ****************************************************** よくわからないのですが何故か文字列の長さを収納する変数lengthが1になているようです。 どうかお力添えください。お願いいたします。 コンパイラはbcc32、OSはWindowsXPです。

  • R-gray
  • お礼率41% (1005/2413)

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

  • ベストアンサー
  • galluda
  • ベストアンサー率35% (440/1242)
回答No.4

がるです。 > しかし何故digit = atoi(&str[i]);はダメで、がるさんの言うように > 別の配列に入れなおすとうまく行くのでしょうか。 うい。ではちょっと詳細に。 例えば、strに 0123 と入ってるとします。正確には文字の後ろに¥0が入っているので、¥0をnで表現するとして 0123n となります。 今回取得したいのは、0であったり1であったりといった「数字一桁」になります。 では、i=0の場合の&str[i]を考えて見ます。 str[i]は今回str[0]になるので、文字の先頭は0になります。ただ、atoiは「char *」を引数として期待しているため、当然のように「¥0があるところまで」を数字として取ってきます。 0123n あれ? これでは、取りたい数字になりません。 # このあたり、元のソースで、atoiの直後に、printfでdigitの値をprintするとわかります。 で。そのために「一文字だけを格納した別領域」を用意してやります。 それがcwk文字配列になります。 ちなみに、cwkは「char work」の略です(笑 ええあまり推奨できるネーミングではありませんが…便利なので、局所に限ってはたまに使います。特にテスト用のコードの場合。 こんなんで説明になりますでしょうか? あと。#3さんのおっしゃるようなやり方もありです。ただしそれはASCIIコードなどに依存するので、一応コメントにそんな風に書いておいたほうがよいです(0-9が不連続にマッピングされているコード体系も存在するので)。

その他の回答 (4)

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

#include <stdio.h> int main(void){ int i; int count[10]={0}; char str[100]; printf("Please input number:"); gets(str); for(i=0;str[i];i++) if('0' <= str[i] && str[i] <= '9') count[str[i]-'0']++; for(i=0;i<=9;i++) printf("'%d' appeared %d times.\n",i,count[i]); return(0); }

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

たいていの場合 '0'~'9' は (文字コード上で) この順に並んでいるので, atoi なんか使わなくても 0~9 に変換できたりします.

回答No.2

このような場合、実行時に出力されるというエラーを併せて書いていただくといいと思います。 とても重要な情報なのですが。 あと、たとえば、エラーが出る場合に、入力を 0 1 2 とか、やってみるといろいろヒントがつかめるものです。 さて、atoi() は、「文字列を数値に」直す関数です。 ですから、 1234567890 と入力した場合、最初の digit の値は、(整数としての)1234567890 になります。 ここで、count[1234567890] をインクリメントしようとして、(設定によっては)エラーが表示されることになります。 あと、length が 1 になる要素はなさそうだと思いますが、そのあたりも、どのように確認したのかがあると、いろいろわかると思います。

R-gray
質問者

お礼

うーん、よくわからないのですが、 つまりatoiは文字列のうちの1個のstr[i]を数値にするのではなく 文字列str全体を数値にすることしか出来ないということでしょうか? つまり digit=atoi(&str[i]);はatoiの使い方が間違っていて digit=atoi(str)という書き方しかできない、ということでしょうか? あとlengthが1になるというのは正直ちょっと違う状況、、、 実は文字を読み込むときgets(str)かscanf("%c",str)なのかわからず 両方試したんですが、後者の時にprintf("%d",length)とすると 1と表示されたのです。なのでgetsのときでは無かったです。 申し訳ありません。

  • galluda
  • ベストアンサー率35% (440/1242)
回答No.1

がると申します。何点か。 1.ループについて 単純に for(; str[i] != '\0'; i++) { でも良いと思うのですがどうでしょうか? 2. できればgetsではなくてfgetsを使うとよいです。 3. データ取得のところですが。 digit = atoi(&str[i]); だとうまくいかないです。 char cwk[4]; を宣言した後に cwk[1] = '\0'; if(str[i]>='0' && str[i]<='9'){ cwk[0] = str[i]; digit = atoi(cwk); という感じでもっていくと、うまくいきます。 # ここがうまくいかない理由が直接的にカウントがうまくいっていない理由です。 参考になれば幸いです。

R-gray
質問者

お礼

・・・うまくいきました!!! おっしゃるとおり3のところが問題だったようです。 しかし何故digit = atoi(&str[i]);はダメで、がるさんの言うように 別の配列に入れなおすとうまく行くのでしょうか。 正直考えてもさっぱりで、願わくばご教授いただきたいです。 あとcwkって何の略なのでしょう。妙に気になります笑。 とにもかくにも、ほんとうにありがとうございます!

関連するQ&A

  • 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言語 文字列の操作

    文字Cが含まれる個数を求めたいです #include <stdio.h> int str_chnum(const char str[],int c) { int i; int count=0; for(i=0;str[i]!="\0";i++) if (str[i]==c) count++; return(count); } int main(void) { char st[100]; printf("検索文字列を入力してください:"); scanf("%s",st) ; printf("検索文字列数は%uです。\n",st,int str_chnum(const str[],int c)); return(0); } コンパイルできません。なぜですか?printfの行がたぶん間違っていると思うんですが。。。

  • C言語で分からないところがあるのですが・・・

    すみません。C言語で分からないところがあったので来ました。 ユーザから数字を任意の数だけ受け取って、その数字とその和を表示するプログラムです。atoiなる関数、そしてコマンドライン引数というのを使って考えてみた結果を下に書きましたので、どなたか修正してください。お願いします。 実行結果(のイメージ図) 20 39 4 sum 20 39 4 63 途中までのソースコードです。 #include <stdio.h> #include <stdlib.h> #include <math.h> int main(int argc,char *argv[]) { int sum; int n,i; printf("How many numbers INPUT?: "); scanf("%d", &n); for(i = 0; i <= n; i++){ atoi(argv[i]); } sum = printf("%d",sum); return 0; }

  • 入力された文字列の中の数字を全てを削除するプログラム(C言語)

    入力された文字列の中の数字を全てを削除するプログラム(C言語) 柴田望洋さんの「明解C言語入門編」という本の演習11-5に当たるこのプログラムの作り方がどうしてもわかりません。 なんとか書いてみましたが、実行してもうまくいきません。 どこが悪いのか自分でもわかりません。 誰か教えてくださいお願いします。 以下が僕が書いたコードです。 #include<stdio.h> void del_digit(char *str){ unsigned i=0; char *a; while(*(str+i)){ if(*(str+i)<0 || *(str+i)>9) *a++=*(str+i); i++; } printf("%s",a); } int main(){ char *str; scanf(" %s",str); del_digit(str); return 0; }

  • C言語の問題で困っています。

    C言語の問題で困っています。 途中までできたのですが、この先が分かりません。 教えて頂くようお願いいたします。 【問題】 文字列の長さを求めるプログラムです。このプログラムを、入力した文字列の文字列長を求めるように変更してみましょう。  ただし、入力する文字列は半角で最大 20 文字までとし、指定された範囲外の値( 21 以上)が入力された場合は、正しい値が入力されるまで入力処理を繰り返すこと。 #include <stdio.h> int main(void) { char str[256] = "Hello"; int length, i; printf("文字列:"); scanf ("%s",str); length=0; i=0; while (str[i]!='\0') { i++; length++; } printf("\n文字列長:%d\n",length); }

  • C言語でこのプログラムを完成させるには

    C言語でこのプログラムを完成させるには C言語初心者です。 1~6の乱数を100回発生させて、それぞれの出現回数をカウントし、ヒストグラムとして表示するプログラムを作成したいのですが上手くいきません。 #include <stdio.h> #include <time.h> #include <stdlib.h> int rnd(int m, int n) { return (int)(n-m+1)*(rand()/(RAND_MAX+0.1))+m; } int main(void) { int i, j, r; int hist[7]; for (i=1; i<7; i++) hist[i]=0; srand((unsigned)time(NULL)); for (i=0; i<100; i++) { r=6; while (6-- > 0) putchar('*'); putchar('\n'); } for (i=1; i<7; i++) { printf("%2d:", i); for (j=0; j<hist[i]; j++) printf("*"); printf("\n"); } return 0; } 何がいけないのでしょうか? よろしくお願いします。

  • C言語のプログラムでおかしな動作をするのですが教えて頂けないでしょうか?

    VisualStudio2008使用しています。 問題は、サイコロを200回振ってその出た目の数の個数分*を表示するプログラムです。 サイコロの目はランダムで出しています。 次のプログラムは正常に動作するものです。 /* #include <stdio.h> #include<stdlib.h> #include<time.h> #define N 200 int DICE(int min,int max); int main() { int n,i,j; int y[7]={0}; srand((unsigned int)time(NULL)); for(i=0;i<N;i++){ n=DICE(1,6); y[n]++; } for(i=1;i<7;i++){ printf(" %2d: ",i); for(j=0;j<y[i];j++){ printf("*"); } printf("\n"); } return 0; } int DICE(int min,int max) { return min+(int)(rand()*(max-min+1.0)/(1.0+RAND_MAX)); } */ 次のプログラムが問題で、授業で先生が配列にはstaticをおまじないとしてつけないと暴走すると言われたので、つけて見ると明らかに間違ってると思われるプログラムで動作するのですが原因を教えて頂けないでしょうか? 以下問題のプログラム! 配列の前にstaticをつけたら、添え字をいくつにしても正常に動作します。普通は添え自分しか領域って確保されないですよね??? /* #include <stdio.h> #include<stdlib.h> #include<time.h> #define N 200 int DICE(int min,int max); int main() { int n,i,j; //以下が問題の配列宣言 static int y[2]={0}; srand((unsigned int)time(NULL)); for(i=0;i<N;i++){ n=DICE(1,6); y[n]++; } for(i=1;i<7;i++){ printf(" %2d: ",i); for(j=0;j<y[i];j++){ printf("*"); } printf("\n"); } return 0; } int DICE(int min,int max) { return min+(int)(rand()*(max-min+1.0)/(1.0+RAND_MAX)); } 質問の意味が正確に伝わらなかった場合は補足しますので、ご回答よろしくお願いします。

  • c言語 プログラム ピラミッド

    プログラミングについて教えてください プログラムは ピラミッドの図形をユーザーが指定した数字で正三角形の ピラミッドの段数を指定できるプログラムです 例えば「5」と打てば ********* ■ ********■■■ ******■■■■■ ****■■■■■■■ **■■■■■■■■■ このような感じに表示されます *の部分は空白です #include<stdio.h> int main (void) { int num,i,j,h; printf("ピラミッドの高さを入力してください : "); scanf("%d" ,&num); for(i=1; i<=num; i++){ for(j=num; j>=i+1; j--){ printf(" ",j); } for(h=1; h<=j; h++){ printf("■"); } printf("\n"); } return 0; } ここまで出来ています、詰まっているのでご教授ください よろしくお願いします

  • C言語 外部変数について

    #include<stdio.h> int count; int f(int x){  int i;  for(i=0 ; x < 10 ; i++){   x*=2;   count++;   }  return x; } int main(void){  count=0;  printf("%d %d",f(1),count);  return 0; } のようなプログラムを作って実行してみたところ f(1)の部分は1024と自分の目的通りの結果が返ってきましたが countの部分が0とでてきてしましました 関数内で10回の繰り返しを行ったので 10がはいってると思ったのですが どこを直せば10の値がでてきますか?

  • C言語でファイルの内容を strtok関数 を使って数字と文字を分けて

    C言語でファイルの内容を strtok関数 を使って数字と文字を分けて配列に格納したいのですが、うまくできません。 どこが駄目なのかご指摘をお願いします! ファイル内容 20 田中 10 鈴木 #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc,char *argv[]) { FILE *fp; char str[256]; char *tp; int i=0; int num[10]; char na[10]; fp=fopen(argv[1],"r"); while(fgets(str,sizeof str,fp)!=NULL); tp = strtok ( str, " " ); while(tp != NULL ) { num[i]=atoi(tp); tp = strtok( NULL," "); if ( tp != NULL ){ na[i]=*tp; } i++; } printf("%d\n%s",num[0],na[0]); printf("%d\n%s",num[1],na[1]); fclose(fp); return 0; }

専門家に質問してみよう