
タイトルのようなプログラムを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です。
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が不連続にマッピングされているコード体系も存在するので)。
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);
}

No.2
- 回答日時:
このような場合、実行時に出力されるというエラーを併せて書いていただくといいと思います。
とても重要な情報なのですが。
あと、たとえば、エラーが出る場合に、入力を
0
1
2
とか、やってみるといろいろヒントがつかめるものです。
さて、atoi() は、「文字列を数値に」直す関数です。
ですから、
1234567890
と入力した場合、最初の digit の値は、(整数としての)1234567890 になります。
ここで、count[1234567890] をインクリメントしようとして、(設定によっては)エラーが表示されることになります。
あと、length が 1 になる要素はなさそうだと思いますが、そのあたりも、どのように確認したのかがあると、いろいろわかると思います。
うーん、よくわからないのですが、
つまり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のときでは無かったです。
申し訳ありません。
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);
という感じでもっていくと、うまくいきます。
# ここがうまくいかない理由が直接的にカウントがうまくいっていない理由です。
参考になれば幸いです。
・・・うまくいきました!!!
おっしゃるとおり3のところが問題だったようです。
しかし何故digit = atoi(&str[i]);はダメで、がるさんの言うように
別の配列に入れなおすとうまく行くのでしょうか。
正直考えてもさっぱりで、願わくばご教授いただきたいです。
あとcwkって何の略なのでしょう。妙に気になります笑。
とにもかくにも、ほんとうにありがとうございます!
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
文字列から空白を取り除きたい...
-
charからLPTSTRへの変換方法
-
配列をnビットシフトする
-
CStringをwchar_tに変換したい
-
C言語のfor文です。 繰り返しの...
-
ftoa の作り方
-
TCP/IP通信型大文字・小文字変...
-
間接参照のレベルが異なっています
-
【C言語】文字型と整数型の違い
-
構造体の各メンバにfor文からア...
-
char型からのバイト数取得
-
charでの計算?
-
char型と言うものがまだ理解出...
-
文字列
-
c言語でソーベルフィルタが作り...
-
C言語のポインターで詰まっている
-
atoi( ) の反対をやりたい
-
c言語でユーザ関数を利用して入...
-
最近のCPUのほとんどはリトルエ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
構造体の各メンバにfor文からア...
-
fgetsなどのときのstdinのバッ...
-
文字列から空白を取り除きたい...
-
C言語のfor文です。 繰り返しの...
-
CStringをwchar_tに変換したい
-
間接参照のレベルが異なっています
-
c++ 文字列を入力して、一文字...
-
C言語の入力した文字を反転させ...
-
charからLPTSTRへの変換方法
-
ネットワークにつながっている...
-
'const char *' 型は 'char *' ...
-
テキストデータをそのままバイ...
-
c言語でユーザ関数を利用して入...
-
atoi( ) の反対をやりたい
-
間接操作のレベルとは
-
-'0'の意味について
-
double型の値をchar配列に変換...
-
Linuxでフォルダ内全ファイル名...
-
配列をnビットシフトする
-
型変換
おすすめ情報