文字列中の各 文字の出現回数を数える

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
porno

文字列中の各 文字の出現回数を数える

#1

投稿記事 by porno » 15年前

すいませんが質問に答えて下さい。

fgets() を使って50文字以下の文字列を入力し,文字列中の各
文字の出現回数を数えるプログラムを作成せよ。
という課題で 
例えば、
%
文字列は? abcdef,abb(ccc110)
a : 2
b : 3
c : 4
d : 1
e : 1
f : 1
, : 1
( : 1
1 : 2
0 : 1
) : 1
という感じに仕上げたいのですがどうしてもうまくいきません。
どうやって出現回数の数を数えることができるのか教えてもらえないでしょうか。

osはlinux、コンパイラはgccです。

一応作りかけのソースを載せておきます。

#include <stdio.h>

# define BUFFER_SIZE (256)

int main(void)
{
int i;
 int count[256];
char buf[BUFFER_SIZE];
printf("Please input :");
fgets(buf, BUFFER_SIZE, stdin);
for(i=0;buf;i++)
{
count[buf]++;
}
for(i=0;buf[i+1]!='\0';i++)
{
printf("'%c' appeared %d times.\n",buf,count[buf]);
}
return(0);
}

ookami

Re:文字列中の各 文字の出現回数を数える

#2

投稿記事 by ookami » 15年前

いろいろ気になるところはありますが、まずは、
int count[256];

int count[256]={0};
ですね。

現状の出力結果も回答の参考になるので、示してもらえるとよいと思いますよ。

porno

Re:文字列中の各 文字の出現回数を数える

#3

投稿記事 by porno » 15年前

返答ありがとうございます。
ソースを直してから実行してみると
Please input number:ghfyug
'g' appeared 2 times.
'h' appeared 1 times.
'f' appeared 1 times.
'y' appeared 1 times.
'u' appeared 1 times.
'g' appeared 2 times.
となり、回数は正しくなりましたがgが二回表示されてしまいます。

また、
int count[256];

int count[256]={0};
なぜこのようにする必要があるのでしょうか。

ookami

Re:文字列中の各 文字の出現回数を数える

#4

投稿記事 by ookami » 15年前

デバッグの手法として「ステップ実行」はご存知でしょうか?活用を強くオススメします。gccが手元にないのでちょっと手順はわかりませんが…

とは言え、これくらいならってことで、
for(i=0;buf[i+1]!='\0';i++)
{
printf("'%c' appeared %d times.\n",buf,count[buf]);
}

for(i=0;i<256;i++)
{
if(count[buf]) printf("'%c' appeared %d times.\n",buf,count[buf]);
}
なぜこうなるのか、お分かりいただけるでしょうか?

> なぜこのようにする必要があるのでしょうか。

これは「c++ 配列 初期化」あたりで検索するとよいと思います。

porno

Re:文字列中の各 文字の出現回数を数える

#5

投稿記事 by porno » 15年前

当たり前のことに気づいてなかったです..
0から数えるのだからすべてを0に初期化しないとだめということですね。

for(i=0;buf[i+1]!='\0';i++)
{
printf("'%c' appeared %d times.\n",buf,count[buf]);
}

for(i=0;i<256;i++)
{
if(count[buf]) printf("'%c' appeared %d times.\n",buf,count[buf]);
}

これの意味がわかりません..
これに直してコンパイルし、実行したところ
おかしくなったのですが..

フリオ

Re:文字列中の各 文字の出現回数を数える

#6

投稿記事 by フリオ » 15年前

 
 結果(count)を表示する際に入力した文字列(buf)を経由しているので、
その文字列に複数回出現する文字は、結果も複数回表示されます。
 
これは、入力した文字列(buf)を使わずに、結果(count)を表示すれば
回避できます。

フリオ

Re:文字列中の各 文字の出現回数を数える

#7

投稿記事 by フリオ » 15年前

 
for(i=0;buf[i+1]!='\0';i++)
{
printf("'%c' appeared %d times.\n",buf,count[buf]);
}

for(i=0;i<256;i++)
{
if(count[buf]) printf("'%c' appeared %d times.\n",buf,count[buf]);
}

 これだと、bufに格納されている文字列の終端を越えて意味のない場所まで参照してしまうので、
結果がおかしくなります。

ookami

Re:文字列中の各 文字の出現回数を数える

#8

投稿記事 by ookami » 15年前

うぅわすいません(汗
「なぜこうなるのか、お分かりいただけるでしょうか?」とか言って私が分かってないっていう… 本当にすみませんでした。

えぇと… その後うまくいきましたでしょうか。

porno

Re:文字列中の各 文字の出現回数を数える

#9

投稿記事 by porno » 15年前

みなさんアドバイスありがとうございます。
一応このソースコードでうまくいったのですが、これであってますか?


#include <stdio.h>
# define BUFFER_SIZE (256)
int main(void)
{
int i;
int count[256]={0},sum[256]={0};
char buf[BUFFER_SIZE];
printf("Please input :");
fgets(buf, BUFFER_SIZE, stdin);
for(i=0;buf;i++)
{
count[buf]++;
}
for(i=0;buf[i+1]!='\0';i++)
{
if(sum[buf]==0)
{
printf("'%c' appeared %d times.\n",buf ,count[buf]);
sum[buf]++;
}
}
return(0);
}

mila

Re:文字列中の各 文字の出現回数を数える

#10

投稿記事 by mila » 15年前

後ろの処理はこうした方がすっきりします。
for (i = 0; i < 256; i++) {
    if (count > 0) {
        printf("%c appeared %d times.\n", i, count);
    }
}

porno

Re:文字列中の各 文字の出現回数を数える

#11

投稿記事 by porno » 15年前

こちらのほうがすっきりしますね。わかりました!
皆さんのおかげで完成することができました。

本当にありがとうございました!

KEYONN_

Re:文字列中の各 文字の出現回数を数える

#12

投稿記事 by KEYONN_ » 15年前

僕も自分なりに作ってみました。
作ったのはいいんですが、期待した動作と違っているような気がします。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define MAX_CODE 93
//93の由来は、ASCIIコード abs(0x21-0x7e)

int CountString(char *String)
{
static int Count[MAX_CODE]={0};
int StringTable[MAX_CODE]={0};

int i,j;

for(i=0;i<strlen(String);i++)
{
Count[String-0x21]++;
StringTable[String-0x21]=1;
}

{
for(i=0;i<MAX_CODE;i++)
{
if(StringTable==1 && Count!=0)
{
printf("%c:%d\n",i+0x21,Count);
}
}
}
}

#define BUFFERSIZE (256)
#define StringLen 50

int main(void)
{
char buf[StringLen];
printf("文字列は?");fgets(buf,BUFFERSIZE,stdin);

CountString(buf);

return 0;
}

porno

Re:文字列中の各 文字の出現回数を数える

#13

投稿記事 by porno » 15年前

そのような方法もあるんですね!

ありがとうございます!!

フリオ

Re:文字列中の各 文字の出現回数を数える

#14

投稿記事 by フリオ » 15年前

 
 charがsignedかunsignedかは処理系によるので、
char buf[BUFFER_SIZE];
は、
unsigned char buf[BUFFER_SIZE];
にしましょう。
 
先に、
>これは、入力した文字列(buf)を使わずに、結果(count)を表示すれば
>回避できます。
と回答しましたが、もし結果表示の順を文字コードではなく、
入力した文字列に依るのなら、
for(i = 0; buf && buf != '\n'; ++ i) 
    { 
        if(count[buf]) 
        { 
            printf("'%c' appeared %d times.\n", buf, count[buf]);  
            count[buf] = 0;
        }
    }

という方法もあります。
 

画像

閉鎖

“C言語何でも質問掲示板” へ戻る