人に聞けない痔の悩み、これでスッキリ >>

数を数えるプログラミングをしています。
あるきまった文字だけをカウントして、その出現回数だけを数えたいのです。
途中まで考えてみたのですが、決まった文字が出現するとこでどうしたらいいか分からなくなりました。
できるだけ自分でやりたいと思ってるので、使える関数や続きの考え方を教えてもらえるとうれしいです。
初心者なのでよろしくお願いします。

a後にbが来たときだけを数えるものです。

char *a;
int i;

moji[20] //abcddcbaが入っている

a = moji;

/*ここから下を考えてる途中*/

if( *a != 0 )
{
for(;*( a+1) != 0; a++ )
{
if( *a == 'a' )
{
if( *(a+1) == 'b' )
{

A 回答 (4件)

#2です。



> abがどこにあっても数えられますかね...
> Abと言う場合もかえられないといけないんです...

strstr
strlen
辺りを使って汎用的な関数を作れば、
"ab"だろうが"Ab"だろうが"cDeF"でもできますよ。
"ab"と"Ab"の2回呼び出してもいいんだから。

でも大文字小文字に対応するなら
toupper
とか使うのが普通だけど
    • good
    • 0

ほとんど完成していると思いますよ。


あとはカウントするくらいでは?
    • good
    • 0

strstrでも使えばどうでしょう?

この回答への補足

abがどこにあっても数えられますかね...
Abと言う場合もかえられないといけないんです...

書いてないことばかりでごめんなさい。

補足日時:2009/10/28 20:59
    • good
    • 0

"ab" の出現回数とは、違うのですか?

この回答への補足

はいそうです。
言い方が悪くてすみません。

補足日時:2009/10/28 19:53
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q文字列中に含まれる文字の個数をカウントするプログラムについて…

文字列、1文字が与えられたとき、これをポインタで入力し文字列中に含まれる文字の個数を計算するプログラムを作成せよ。

と、いう課題がだされたんですけど、ユーザが任意の文字列と1文字を入力できるようにすることができません…。
多分main関数の部分をちょっといじくればよいと思うのですが…。
どなたかアドバイスをお願いします。
#include <stdio.h>

int count(const char *str, const char ch)
{
int cnt=0;
while (*str!='\0')
{
if (*str==ch)
cnt++;
str++;
}
return cnt;
}

int main()
{
const char *str="hello,world!";
const ch='o';

int cnt;

cnt=count(str, ch);

printf("%s中に%cは%d個です\n", str, ch, cnt);


return 0;
}

文字列、1文字が与えられたとき、これをポインタで入力し文字列中に含まれる文字の個数を計算するプログラムを作成せよ。

と、いう課題がだされたんですけど、ユーザが任意の文字列と1文字を入力できるようにすることができません…。
多分main関数の部分をちょっといじくればよいと思うのですが…。
どなたかアドバイスをお願いします。
#include <stdio.h>

int count(const char *str, const char ch)
{
int cnt=0;
while (*str!='\0')
{
if (*str==ch)
...続きを読む

Aベストアンサー

scanf"%s", str)は、バッファオーバーフローの危険と改行文字の食べ残し問題がありますね。
-- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< --
int main()
{
char ch;
char str[BUFSIZ];
int cnt;

printf("文字列を入力して下さい > ");
fgets(str,BUFSIZ,stdin);

printf("カウントする文字を入力してください > ");
ch = getchar();

cnt=count(str, ch);
printf("%s中に%cは%d個です\n", str, ch, cnt);

return 0;
}

Q数字文字をカウントするプログラムの動作について

良い質問のタイトルが思い浮かばず、分かりづらいタイトルで申し訳ありません、C言語について質問させて頂きます。
C言語の参考書を買って夏休み中にプログラムの勉強をしているのですが、何故動作するのかがわからない例があります、ソースは以下の通りです。

#include <stdio.h>

int main(void)
{
int i,ch;
int cnt[10] = {0};

while(1)
{
ch = getchar();
if (ch==EOF) break;

switch(ch)
{
case '0' : cnt[0]++;printf("%d\n",ch);break;/* printfは確認の為 */
case '1' : cnt[1]++;printf("%d\n",ch);break;
case '2' : cnt[2]++;printf("%d\n",ch);break;
case '3' : cnt[3]++;printf("%d\n",ch);break;
case '4' : cnt[4]++;printf("%d\n",ch);break;
case '5' : cnt[5]++;printf("%d\n",ch);break;
case '6' : cnt[6]++;printf("%d\n",ch);break;
case '7' : cnt[7]++;printf("%d\n",ch);break;
case '8' : cnt[8]++;printf("%d\n",ch);break;
case '9' : cnt[9]++;printf("%d\n",ch);break;
}
}

puts("数字文字の出現回数");
for(i=0;i<10;i++)
printf("'%d':%d\n",i,cnt[i]);
getchar();getchar();

return(0);
}

といったプログラムです。

実行し、数値を入力、CTRL+Zで入力を終了し、出現回数を表示させる、という動作自体は無事にできるのですが、何故chの値が変更していくのかがわかりません、数値を入力した時点で51や49といったそれぞれ違う数値が表示されるのですが、chの値を変更させる命令を、何が引き起こしているのかが理解できません、3(51)と判定されて同じ数が無限にカウントされないのは何故なのでしょうか・・・・?

また、その後の無限ループからの脱出をCTRL+Zがどうして引き起こすのかも理解できず困っています、教科書には「CTRL+Zは入力の終了を意味する」とあるのですが、これは一体どういう意味なのでしょうか、強制的に割り込んでEOFを代入するということなのでしょうか・・・?

お時間がある時にでも、教えて頂けると助かります、よろしくお願いします。

良い質問のタイトルが思い浮かばず、分かりづらいタイトルで申し訳ありません、C言語について質問させて頂きます。
C言語の参考書を買って夏休み中にプログラムの勉強をしているのですが、何故動作するのかがわからない例があります、ソースは以下の通りです。

#include <stdio.h>

int main(void)
{
int i,ch;
int cnt[10] = {0};

while(1)
{
ch = getchar();
if (ch==EOF) break;

switch(ch)
{
case '0' : cnt[0]++;printf("%d\n",ch);break;/* printfは確認の為 */
case '1' : cnt[1]++;printf("%d\n",ch);b...続きを読む

Aベストアンサー

>getchar関数とは入力した文字を順番に3、.、1、4、と返す関数ということなのでしょうか・・?

基本的にはそれで合ってます。
ただ、'3'、'.'、'1'、'4'という文字そのものを返す訳ではなく、アスキーコードを返します。
http://e-words.jp/p/r-ascii.html

平たくいうと、コンピュータは0と1の世界ですから、'a'などの文字も数値としてハードディスクに保存する必要があります。人間が見て分かる文字とコンピュータの世界のコードとの対応表がアスキーコード表です。
OSを始め様々なソフトが、この保存された数値を人間が見て分かりやすい文字に変換してくれてるわけです。


今回の例で言うと、入力された数値をアスキーコードではなく、配列の添字として使いたいので、
int index = ch - '0';
としています。

int index = ch - 48;
でもいいんですが、マジックナンバー(プログラム中に書かれた0, 1以外の数値)を嫌う人もいますので、'0'としています。



printfで%dで出力すると、アスキーコードの値がそのまま出力されます。
これを入力した文字そのものを出力したい場合は、%cを使用します。

>getchar関数とは入力した文字を順番に3、.、1、4、と返す関数ということなのでしょうか・・?

基本的にはそれで合ってます。
ただ、'3'、'.'、'1'、'4'という文字そのものを返す訳ではなく、アスキーコードを返します。
http://e-words.jp/p/r-ascii.html

平たくいうと、コンピュータは0と1の世界ですから、'a'などの文字も数値としてハードディスクに保存する必要があります。人間が見て分かる文字とコンピュータの世界のコードとの対応表がアスキーコード表です。
OSを始め様々なソフトが、この保存された数...続きを読む

QC言語のステップ数をカウントするプログラムについて

C言語のステップ数をカウントするプログラムについて教えてください。空白行・コメント行・実行行・そして全ステップ数をカウントします。全ステップ数については以下のように考えましたが空白行、コメント行をどのようにしたらよいかわかりません。ご指導宜しくお願いいたします。

※コメント行は// や/* */を対象にします
※空行はタブと改行のみの行も含みます

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

int main()
{
int linecnt; //行数
   int a;
   FILE *fp;

   fp = fopen("test.txt", "r");
if(fp == NULL){
printf("入力ファイルがオープン失敗\n");
exit(1);
}

linecnt = 1;

while(feof(fp) ==0){
a = fgetc(fp);
linecnt++;
}

printf("全ステップ数 = %d", linecnt);

return 0;
}

C言語のステップ数をカウントするプログラムについて教えてください。空白行・コメント行・実行行・そして全ステップ数をカウントします。全ステップ数については以下のように考えましたが空白行、コメント行をどのようにしたらよいかわかりません。ご指導宜しくお願いいたします。

※コメント行は// や/* */を対象にします
※空行はタブと改行のみの行も含みます

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

int main()
{
int linecnt; //行数
   int a;
   FILE *fp;

   fp = fope...続きを読む

Aベストアンサー

下記のサイトにソースを投稿しましたので参照にしてください。
http://climbi.com/b/8059/0

今回の質問は、C言語のソース解析を行いますが、厳密に行おうとするとC言語のコンパイラ
が行っている構文解析と同等の処理が要求されます。
それなので、簡易版の形で書いてみました。(バグがあるかもしれませんの自己責任でご使用ください)
作成方針は以下の通り。
1.1行の長さは1024バイト以内が前提
2.コンパイルが正常に完了したソースであることが前提
3.コメントの扱いは以下の通り
  /*から*/までをコメントとみなす。(複数行にまたがることを考慮する)
  //以降をコメントとみなす。(1行のみで、複数行にまたがることはない)
4.空白行の扱いは以下の通り
  行の先頭から終端迄、空白、タブのみで構成される行(空白、タブがなくても良い)
  /* から */の間にある空白行は、コメント行として扱う
5.上記3,4以外の文字が出現した場合、実行文とみなす。
6.ダブルクオート(")ではさまれた文字列中に、/*、*/、//等があってもコメントとは扱わず
  普通の文字列として扱う。
  例
  "aascii// abcd " はコメントではない
  "/* abcd */" はコメントではない
7.ダブルクオート(")の終端は\で修飾されないダブルクオート(")とする。
  例
  "abc" 最後"がダブルクオート終端
  "ab\"" 最後の"がダブルクオート終端
  "ab\"a\"a" 最後の"がダブルクオート終端
  "a\\" 最後の"がダブルクオート終端
8.シングルクオート(')で挟まれたダブルクオートは普通の文字として扱う。
  例
  '"'  普通のデータ(上記6,7の扱いをしない)
  '\"'  同上

9.各行のカウントは以下の通り
  コメントのみで構成させれる行をコメント行としてカウントする
  空白行のみで構成させれる行を空白行としてカウントする
  上記以外を実行行としてカウントする

尚、実際にソースステップをカウントするツールがあるので、それと比較してみました。
下記サイトのRakuStepCounterをダウンロードして実行した結果、こちらで作成した結果と同じ結果に
なりました。(多少のソースの比較のみです)
http://www.rakuchinn.jp/rakustepcounter.html

このソースをstep_count.cとして自分自身のソースをカウントすると以下のようになります。
総ステップ数=223
実行行数=184
コメント行数=37
空白行数=2

尚、136行に
printf("%d:%s\n",All_count,type);
がありますが、各行がどの行に属するのかを印字しています。
これが煩わしい場合は、コメントアウトしてください。

下記のサイトにソースを投稿しましたので参照にしてください。
http://climbi.com/b/8059/0

今回の質問は、C言語のソース解析を行いますが、厳密に行おうとするとC言語のコンパイラ
が行っている構文解析と同等の処理が要求されます。
それなので、簡易版の形で書いてみました。(バグがあるかもしれませんの自己責任でご使用ください)
作成方針は以下の通り。
1.1行の長さは1024バイト以内が前提
2.コンパイルが正常に完了したソースであることが前提
3.コメントの扱いは以下の通り
  /*から*/までをコ...続きを読む

Q再起呼び出しの回数をカウントするプログラム

現在学校の課題で
プログラムを組んでるんですが
ちょっとよくわからないことがあるので教えてください

再起呼び出しの回数をカウントして
その回数を返したいのですが

例えば

coid honoi(int n,char a,char b,char c)  {
    int count=0;
    if (n>0)  {
        hanoi(n-1,a,c,b);
        count++;
    }
}

のようなプログラムを組むと
hanoi(n-1,a,c,b)
を呼び出すと、countが再度 0 に戻され
count=1 になってしまいます。

同様に

if()  {
    int count=0;
    hanoi();
    count++
}

としても、count=1のままでした。

再起呼び出しをするたびに、この count値を増やしていくには
どのようにプログラムを書けばよいのでしょうか?

まだCは初心者レベルなので
易しめにご説明ください。
よろしくお願いします。

現在学校の課題で
プログラムを組んでるんですが
ちょっとよくわからないことがあるので教えてください

再起呼び出しの回数をカウントして
その回数を返したいのですが

例えば

coid honoi(int n,char a,char b,char c)  {
    int count=0;
    if (n>0)  {
        hanoi(n-1,a,c,b);
        count++;
    }
}

のようなプログラムを組むと
hanoi(n-1,a,c,b)
を呼び出すと、countが再度 0 に戻され
count=1 になってしまいます。

同様に

if()  {
...続きを読む

Aベストアンサー

関数の外で変数を宣言し、どこかで初期化して、カウントアップすれば実現できます。

static int count;
  :
  :
int main(int argc, char *argv[]) {

  :
  :
  count = 0;
  hanoi(適当な引数);
  :
  :

}
void hanoi(int n,char a,char b,char c)  {
    count++;
    if (n>0)  {
        hanoi(n-1,a,c,b);
    }
}

こんな感じです。

Q数字文字の出現回数を表示するプログラム(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です。

タイトルのようなプログラムを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を実行すると数字入力後エラーメッセージが...続きを読む

Aベストアンサー

がるです。

> しかし何故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が不連続にマッピングされているコード体系も存在するので)。

がるです。

> しかし何故digit = atoi(&str[i]);はダメで、がるさんの言うように
> 別の配列に入れなおすとうまく行くのでしょうか。
うい。ではちょっと詳細に。

例えば、strに
0123
と入ってるとします。正確には文字の後ろに¥0が入っているので、¥0をnで表現するとして
0123n
となります。
今回取得したいのは、0であったり1であったりといった「数字一桁」になります。
では、i=0の場合の&str[i]を考えて見ます。
str[i]は今回str[0]になるので、文字の先頭は0になります。ただ、atoiは...続きを読む

Qセグメンテーション違反

C言語を使用しています。

構造体に値をいれようとしたら、コンパイルは出来るのですが、実行時に
「セグメンテーション違反です (core dumped)」
となってしまい、それ以上行えません。

構造体と代入したい変数との型は、合っています。

いろいろ本などで見ましたが、何が原因かわからず困っています。
教えてください。
宜しくお願いします。

Aベストアンサー

OSは何でしょうか。コンパイラは何を使用していますか?
通常、デバッグオプションをつけて実行すると、異常の発生したソースの箇所で止まりますので、それが手がかりになります。またNo1の方が言われてますように、ソースが公開できるのであれば、ソースを提示するのが良いかと思います。

Q戻り値の意味がわかりません…

戻り値とはどういう値なのか簡単な例文で教えて頂けますか?

Aベストアンサー

バカくさいかもしれませんが簡単な例えをだしてみます。
2人の子供がいて、名前をそれぞれ太郎・花子にしましょう。この2人の子にある役割を決めます。
・花子は飴をもらうと、それをチョコにする役割。(できるかは別として)
・太郎は花子を呼んで飴をあげる役割。

さてこの例では太郎の飴が引数(ひきすう)になり
花子のチョコが戻り値になります。

このイメージを元に次の文を読んでみてください。

「プログラム中の関数やサブルーチンが処理を終了し
呼び出し元に処理の結果として返す値。」

これが戻り値の正しい定義です。
そのほかにはNo1さんのような役割指すときも、それを「戻り値」と呼んだりします。

QC言語で簡単なゲームを作る方法

僕はC言語を学び始めた程度ですが、一番簡単に作れるゲームとその作り方(ソース)を教えて下さい。お願いします。

Aベストアンサー

★じゃんけんゲームのソースです。

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

// じゃんけん定数
#define JKN_GOO  (0)
#define JKN_CHOKI (1)
#define JKN_PA  (2)

// 勝敗の定数
#define TYP_KATI (0)
#define TYP_MAKE (1)
#define TYP_AIKO (2)

// じゃんけんの判定関数
int check( int human, int computer )
{
 if ( human == computer ){
  return TYP_AIKO;
 }
 switch ( human ){
  case JKN_GOO:  return ((computer == JKN_CHOKI) ? TYP_KATI : TYP_MAKE);
  case JKN_CHOKI:  return ((computer == JKN_PA) ? TYP_KATI : TYP_MAKE);
  case JKN_PA:  return ((computer == JKN_GOO) ? TYP_KATI : TYP_MAKE);
  default:   return -1;
 }
}

// じゃんけんゲーム
int main( void )
{
 // ゲーム変数
 int count;  // 勝負回数
 int kati = 0; // 勝ちカウンタ
 int make = 0; // 負けカウンタ
 // 一時変数
 int human;  // キー入力の一時変数(人間用)
 int computer; // 乱数発生の一時変数(コンピュータ用)
 
 // (6)じゃんけん勝負を10回行う
 printf( "★じゃんけんゲーム(10回勝負)\n\n" );
 for ( count = 1 ; count <= 10 ; count++ ){
  // (1)人間:3つの状態を入力
  printf( "%2d回目…[1]グー [2]チョキ [3]パー を入力して下さい:", count );
  do {
   // (2)キー入力
   switch ( getche() ){
    case '1': human = JKN_GOO; break;
    case '2': human = JKN_CHOKI; break;
    case '3': human = JKN_PA; break;
    default: human = -1; break;
   }
  } while ( human == -1 );
  
  // (3)コンピュータ:3つの状態を乱数で決める
  computer = (rand() % 3);
  // (4)人間vsコンピュータの勝負
  switch ( check(human,computer) ){
   case TYP_KATI:
    kati++;
    printf( "⇒勝ち。\n" );
    break;
   case TYP_MAKE:
    make++;
    printf( "⇒負け。\n" );
    break;
   case TYP_AIKO:
    printf( "⇒引き分け。\n" );
    break;
   default:
    printf( "⇒エラー。\n" );
    break;
  }
 }
 // (7)結果表示
 printf( "\n★じゃんけんゲームの結果\n" );
 printf( "人間    :%d 回勝ち\n", kati );
 printf( "コンピュータ:%d 回勝ち\n", make );
 printf( "※引き分け回数は %d 回でした。\n", (10 - kati - make) );
 return 0;
}

注意:全角空白をタブ文字に変換して下さい。

★じゃんけんゲームのソースです。

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

// じゃんけん定数
#define JKN_GOO  (0)
#define JKN_CHOKI (1)
#define JKN_PA  (2)

// 勝敗の定数
#define TYP_KATI (0)
#define TYP_MAKE (1)
#define TYP_AIKO (2)

// じゃんけんの判定関数
int check( int human, int computer )
{
 if ( human == computer ){
  return TYP_AIKO;
 }
 switch ( human ){
  case JKN_GOO:  return ((computer == JKN_CHOKI) ? TYP...続きを読む

Q文字数と単語数を数えるプログラム

When in Rome, do as the Romans do.
をchar形配列に格納し、文字列に含まれる(空白以外の)文字数と単語数を数え、結果を画面に出力するプログラムがうまくできません。文字数と単語数の数え方がさっぱり…
アドバイスしていただけると幸いです。よろしくお願いします

Aベストアンサー

文字数も数えると云う事なので、左から右端(NULL文字)まで1文字ずつ
走査して行きます。ここで、単語も構成する文字がA-Z,a-zであるとして、
文字から空白や記号(','や'.'、NULL文字も含む)に変わったら一つの単語
とします。

具体的には、

1. カウンタ、フラグを初期化
2. NULL文字になるまで繰り返し
3. 文字かどうか判定する
4. 文字なら文字をカウントして、フラグをセット
5. 文字でないなら、
6. フラグがセットされていれば単語数をカウントしフラグをおろす
7. フラグがセットされていないのなら何もしない
8. 1へ

でいけると思います。

Q答えを教えてください

「二つの整数値を読み込んで、
前者の値が後者の何%であるか表示する
プログラムを作成せよ」
お願いします

Aベストアンサー

doubleを使わないなら
(タイプミスも修正)

void main()
{
int var1, var2;
int per;

printf("\n1個目=>");
scanf("%d", &var1);
printf("\n2個目=>");
scanf("%d", &var2);
per = (100 * var1) / var2;
printf("\n<%d>は<%d>の<%d%>だってば!\n", var1, var2, per);
}


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング