タイトルのようなプログラムを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で質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# str[j++]の意味 2 2022/08/30 16:20
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語 3 2022/11/09 13:27
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
charでの計算?
-
文字列から空白を取り除きたい...
-
c++ 文字列を入力して、一文字...
-
C言語のfor文です。 繰り返しの...
-
enumの記述について。
-
プログラムを作成(c言語)
-
'const char *' 型は 'char *' ...
-
下記のプログラムがコンパイラ...
-
int main()の・・・
-
Linuxでフォルダ内全ファイル名...
-
C言語の入力した文字を反転させ...
-
charからLPTSTRへの変換方法
-
【C言語】文字型と整数型の違い
-
pingの結果を取得する方法
-
strlen関数と同じ働きをする関...
-
sprintf関数の作り方
-
atoi( ) の反対をやりたい
-
C言語 共用体について コマンド...
-
3桁区切(コンマ)記号をつけ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
charからLPTSTRへの変換方法
-
charでの計算?
-
配列をnビットシフトする
-
'const char *' 型は 'char *' ...
-
型変換
-
テキストデータをそのままバイ...
-
文字列から空白を取り除きたい...
-
CStringをwchar_tに変換したい
-
絶対パスからのファイル名の切...
-
fgetsなどのときのstdinのバッ...
-
ネットワークにつながっている...
-
str系関数を使わずに二つの文字...
-
3桁区切(コンマ)記号をつけ...
-
atoi( ) の反対をやりたい
-
double型の値をchar配列に変換...
-
C言語のfor文です。 繰り返しの...
-
switch文で文字を比較すること...
-
ファイル名である文字列からbas...
-
c++ 文字列を入力して、一文字...
-
strncpyと_tcsncpy_sのヌルの扱...
おすすめ情報