OCN光で最大124,800円おトク!

文字列を入力し母音だけを出力するプログラムを作りました。
以下だと小文字の母音しか出力できないので大文字にも対応させたいのですが、switch文のcaseを増やすと冗長になってしまう気がします。
switch文以外の方法でもっと簡潔に書く方法はありますか?ご教授お願い致します。

/*
入力した文字列のうち、母音「a,i,u,e,o」だけ出力する
*/

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

#define MAXSTR 256


int main(void)
{
char str[MAXSTR];
int i;

gets(str);

for (i = 0; i < strlen(str); i++)
switch (str[i]) {
case 'a':
putchar(str[i]);
break;
case 'i':
putchar(str[i]);
break;
case 'u':
putchar(str[i]);
break;
case 'e':
putchar(str[i]);
break;
case 'o':
putchar(str[i]);
break;
}
putchar('\n');

return 0;
}

実行結果:
What time is it now?
aieiio

このQ&Aに関連する最新のQ&A

A 回答 (4件)

#include <stdio.h>


#include <string.h>

#define MAXSTR 256

int main(void)
{
char str[MAXSTR];
int i,j;
char cmp[] = "aiueoAIUEO";

fgets(str,MAXSTR,stdin);

for (i = 0; i < strlen(str); i++)
for (j = 0; j < strlen(cmp); j++)
if(str[i] == cmp[j]){
putchar(str[i]);
break;
}

return 0;

こんな感じでどうでしょう。
    • good
    • 0
この回答へのお礼

具体的な回答ありがとうございます。
コードを見て、何故fgetsを使うのだろうと思い調べてみました。
getsは使わない方が良いんですね。実際にMAXSTRの値を短くして、それ以上の入力を与えてみたらプログラムが強制終了してしまいました。fgetsだとちゃんとMAXSTRの長さで入力を切ってくれました。
これからはfgetsを使うようにします。

お礼日時:2006/11/28 20:52

ループ部分だけ。



for (i = 0; i < strlen(str); i++)
if(strchr("aiueoAIUEO",str[i]))
putchar(strchr[i]);
    • good
    • 0
この回答へのお礼

strchr関数を使う方法ですね。
こんな便利な関数があったとは・・・今までよくヘッダ内の関数について調べたことがなかったので、今度じっくり調べてみます。ありがとうございました。

お礼日時:2006/11/28 20:55

「指定した文字(char)が母音かどうかを判定する関数」を作って、修理を分けると見やすくなるかと。

    • good
    • 0
この回答へのお礼

母音を判定し出力するという関数にして作ってみました。
これだけだと余り変わりませんが、もっと長いプログラムになった場合は見やすくて応用がききそうですね。ありがとうございました。

お礼日時:2006/11/28 20:59

母音も別の配列に入れて


多重ループにすれば?
 外側が入力文字列配列のループで
  内側が母音配列のループ
   内側は一致すればputcharして抜けるようにする。
    • good
    • 0
この回答へのお礼

ありがとうございます。
なるほど、配列に母音を格納して比較するという手がありましたね。

皆さんの御回答を参考に早速作り直してみました。
/*
入力した文字列のうち、母音だけ出力する
*/

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

#define MAXSTR 256


/* 母音を判定し出力する */
void vowel(char *str)
{
int i, j;
char cmp[] = "aiueoAIUEO";

for (i = 0; i < strlen(str); i++)
for (j = 0; j < strlen(cmp); j++)
if (str[i] == cmp[j])
putchar(str[i]);
putchar('\n');
}

int main(void)
{
char str[MAXSTR];

fgets(str, MAXSTR, stdin);

vowel(str);

return 0;
}

お礼日時:2006/11/28 20:46

このQ&Aに関連する人気のQ&A

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

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

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

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

QC言語で、入力された、文字列を逆に並べるプログラム。

タイトルのとおりのプログラムをつくりたいんです。
例えば、abcと入力したら、cbaと返してくれるものです。
条件として、ポインタを使えと言われています。
自分で書いたソースは、

0: #include<stdio.h>
1: char re(char *s);
2: main()
3: {
4:char s[10];
5:gets(s);
6:re(s);
7:printf("%s\n",s);
8: }
9:
10: char re(char *s){
11:char c[10];
12:
13:c[9]=s[0];
14:c[8]=s[1];
15:c[7]=s[2];
16:c[6]=s[3];
17:c[5]=s[4];
18:c[4]=s[5];
19:c[3]=s[6];
20:c[2]=s[7];
21:c[1]=s[8];
22:c[0]=s[9];
23:
24:return c[10];
}

C言語を勉強し始めたばかりで、なかなか思うようにかけないでいます。
文字列を入力するのは、4行目~7行目で大丈夫だと思うんですよ。
文字列を逆に並べる、関数 re(char *s)を作れずにいます。
配列s[10]に入っている、文字を最後から取り出して、c[10]にいれていけば、ひっくり返ると思っているんですが、作れません。
13行~21行目の作業も、whileかforでループさせるべきなのもわかってるんですが、条件をどうしたらいいか分からずに作れずにいます。今のソースのまま実行しても、入力したまま出力してしまいます。
さらに、ポインタも今日はじめて勉強して、うっすらと知ってるくらいなので、アドレスとかが、イメージできないでいます。
ながくなってすいません。アドバイスいただきたいです。よろしくおねがいします。

タイトルのとおりのプログラムをつくりたいんです。
例えば、abcと入力したら、cbaと返してくれるものです。
条件として、ポインタを使えと言われています。
自分で書いたソースは、

0: #include<stdio.h>
1: char re(char *s);
2: main()
3: {
4:char s[10];
5:gets(s);
6:re(s);
7:printf("%s\n",s);
8: }
9:
10: char re(char *s){
11:char c[10];
12:
13:c[9]=s[0];
14:c[8]=s[1];
15:c[7]=s[2];
16:c[6]=s[3];
17:c[5]=s[4];
18:c[4]=s[5];
19:c[3]=s[6];
20:c[2]=s[7];...続きを読む

Aベストアンサー

char re(char *s) → void re(char *s)に変更して。

void re(char *s)
{
 char *p;
 p=s+strlen(s)-1;
 while(s<p){
  c=*s;
  *s=*p;
  *p=c;
  s++;
  p--;
 }
}

これでどうでしょうか? pの初期値は末尾の文字の位置です。
先頭と末尾の文字を順番に入れ替えながら内側に進めます。

QC言語:小文字を大文字に変換する関数を作成

C言語超初心者です。学校の課題で次のような問題が出されました。

・問題・
次に挙げる縛りに沿い、以下の関数とメイン関数を作り、処理結果を画面に作成しなさい。

char *tst(char *str)

・strの中の文字列も小文字を大文字に変換し、変換した文字列が格納されているchar *に返す。

・引数strの中の文字列は受け取った状態で手を加えない。

・関数内でmalloc関数を使用し、領域を確保して大文字に変換した文字列を格納しreturnでポインタを返す。

・malloc関数を使用する。

----------------------------------------------------------------------------------


大文字に変換するには

while(*str != '\0') {

if(*str >= 'a' && *str <= 'z') {

*str -= 'a'- 'A';
}
++str;
}

というのは分かったのですがここから何をすするか全く分かりません。初心者なのでなるべく分かりやすく教えてもらえると有難いです。

お願いします。

C言語超初心者です。学校の課題で次のような問題が出されました。

・問題・
次に挙げる縛りに沿い、以下の関数とメイン関数を作り、処理結果を画面に作成しなさい。

char *tst(char *str)

・strの中の文字列も小文字を大文字に変換し、変換した文字列が格納されているchar *に返す。

・引数strの中の文字列は受け取った状態で手を加えない。

・関数内でmalloc関数を使用し、領域を確保して大文字に変換した文字列を格納しreturnでポインタを返す。

・malloc関数を使用する。

-----------------------------...続きを読む

Aベストアンサー

>というのは分かったのですがここから何をすするか全く分かりません。

 というのが分かって、「ここから何をすするか全く分かりません」てのは、ヘン。


過去の「質問」を検索(「大文字に変換」、「malloc」)して、作ってみました。

>小文字を大文字に変換

 http://oshiete.goo.ne.jp/qa/3295844.html

 #7 さんの「素直に標準関数(touuper)を使うのが吉」を採用。

>malloc関数を使用する。

 http://oshiete.goo.ne.jp/qa/5651516.html

 ここの確保量 200 の代わりに、strlen( str ) を使用。

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

char *tst( char *str )
{
 int iLen;
 char *cap;

 iLen = strlen( str );

 cap = (char *)malloc( iLen + 1 );

 if( NULL == cap ){ // ここ、「課題」なら必要かも
  fprintf( stderr, "メモリ確保失敗" );
  exit( 9 );
 }
 while( *str ){

  *cap = toupper( *str );

  cap++;
  str++;
 }
 *cap = '\0'; // 文字列終端

 return( cap - iLen );
}
int main()
{
 char *ans;
 char str[ 64 ] = "htTp://okwaVe.jp/QA/q5651516.html";

 ans = tst( str );

 printf( "%s\n", str );
 printf( "%s\n", ans );

 free( ans ); // 確保領域解放

 return( 0 );
}
注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。

>というのは分かったのですがここから何をすするか全く分かりません。

 というのが分かって、「ここから何をすするか全く分かりません」てのは、ヘン。


過去の「質問」を検索(「大文字に変換」、「malloc」)して、作ってみました。

>小文字を大文字に変換

 http://oshiete.goo.ne.jp/qa/3295844.html

 #7 さんの「素直に標準関数(touuper)を使うのが吉」を採用。

>malloc関数を使用する。

 http://oshiete.goo.ne.jp/qa/5651516.html

 ここの確保量 200 の代わりに、strlen( str ) を使用。

#...続きを読む

Qc言語でAからZまでを表示するプログラム

#include <stdio.h>

int main(void)
{
char C;

for (C = 'A';C <= 'Z';C++) {
printf("%c",C);
}
printf("\n");

return 0;
}

これ以外の作り方を知っているという方、ぜひ教えてください。

Aベストアンサー

#include <stdio.h>

int main(void)
{
 int a;

 for(a = 'A';a <= 'Z';a++) {
  putchar(a);
 }
 putchar('\n');

 return 0;
}



#include <stdio.h>

int main(void)
{
 char *str = "ABC (中略) XYZ\n";

 do {
  printf("%c", *str);
  str++;
 } while(*str);

 return 0;
}

質問が抽象的過ぎるので「これ以外の作り方」だとどうとでもできそうな気がしますけど。

Qscanf("%s", buf);でスペースを含んだ文字

コンソールプログラムで
scanf("%s", buf);
を使用してユーザに入力された文字によって処理を行いたいのですが、このままではスペースを含む文字列がスペースの手前で切られてしまいます。
C:\Program Filesなどを入力可能にさせたい場合にはどのようにするのがベターですか?

Aベストアンサー

お任せください!
そもそもscanfを使うというのはお勧めでは
ありません。scanfは文字+改行文字が入力
されないと完了しないためです。
が、それは良しとしましょう。
scanfの書式ですが、

int n = scanf("%[^\r\n]",buf);

という便利な書式があります。
perlでもおなじみの書式ですね。
上記の山文字"^"より前が読み込ませたい文字の集まりで、ハイフン指定が出来ます。
"^"より後ろが読込みを停止させたい文字の集まりです。上記の指定は復帰改行以外の文字が現れるまで読み込みます、という書式です。
下記のような指定も出来ます。

int n = scanf("%[a-zA-Z0-9\\: \t^\r\n]",buf);

なお、戻り値は読み込んだ項目数ですので、
if(n >= 1)
{
}
で判断できますね。

QC言語 While文(ループ)内の文字入力

While文で、1文字入力をやれば思うようにうまくいかない。数字(データ)入力や、文字列入力の場合(%d 及び %s)ならうまくいく。文面で説明するより実際のプログラムを見た方が分かりやすいと思うので、以下にプログラムとその実行結果、実行結果に対する私が意図している結果とを示します。

【プログラム部分】
#include<stdio.h>

int main(void)
{
   char a;

   while(1)
   {
   printf("1文字を入力:");
   scanf("%c",&a);

   if(a == 'x')
     break;

   printf("入力したのは %c です。\n",a);
   }

   return 0;
}

【実行結果(キーボードからは「 e 」と入力」)】
1文字を入力:e
入力したのは e です。
1文字を入力:入力したのは
です。
1文字を入力:

【私が意図している結果】
1文字を入力:e
入力したのは e です。
1文字を入力:


 ちなみにC言語の環境は、インターネットで無料で入手できる試食版です。(LSI C-86 Ver3.30c 試食版)
 上記プログラムを見てもらえればお分かりだと思いますが、「xを入力するまで、永遠と1文字入力とその表示を行う」ことを意図しています。しかし実際の結果は意図に反しています。
 1回目は正常に動作しているようですが、問題は2回目以降。scnafで入力待ちをすることなく、なぜかscanfをスルーする形で3回目のscanf入力待ちとなっています。この理由を教えてください。お願いします。

While文で、1文字入力をやれば思うようにうまくいかない。数字(データ)入力や、文字列入力の場合(%d 及び %s)ならうまくいく。文面で説明するより実際のプログラムを見た方が分かりやすいと思うので、以下にプログラムとその実行結果、実行結果に対する私が意図している結果とを示します。

【プログラム部分】
#include<stdio.h>

int main(void)
{
   char a;

   while(1)
   {
   printf("1文字を入力:");
   scanf("%c",&a);

   if(a == ...続きを読む

Aベストアンサー

>1文字を入力:入力したのは
>です。

は、[Enter]キーの入力によるためです。
[Enter]キーをスルーする必要があります。

   char a;
char dummy; /*[Enter]キー用*/

   while(1)
   {
   printf("1文字を入力:");
   scanf("%c",&a);
scanf("%c",&dummy); /*[Enter]キー用*/

   if(a == 'x')
     break;

   printf("入力したのは %c です。\n",a);
   }


で、どうでしょうか?

Qc言語の文字列の逆順のプログラムがわかりません

文字列を逆順して出力するプログラミングがわかりません。
#include <stdio.h>
#include <string.h>

void reverse(char *moji, char *gyaku);

int main(void)
{
char x[30];
char y[30];

puts("文字を入力してください。\n");
scanf("%s", x);

reverse(x, y);

printf("逆順すると%sです。\n", y);

return (0);
}

void reverse(char *moji, char *gyaku)
{
int i, len;

len = strlen(moji);

gyaku = moji + len - 1;

for(i = 0; i < len; i ++){
putchar((int)*gyaku);
gyaku--;
}
}


理想とする実行結果は
文字を入力してください。
abcdefg
逆順するとgfedcbaです。

なんですが、
上記のソースを実行すると

文字を入力してください。
abcdefg
gfedcba逆順すると(謎の漢字)です。

となります。

どこがおかしいんでしょうか?
よろしくおねがいします。

文字列を逆順して出力するプログラミングがわかりません。
#include <stdio.h>
#include <string.h>

void reverse(char *moji, char *gyaku);

int main(void)
{
char x[30];
char y[30];

puts("文字を入力してください。\n");
scanf("%s", x);

reverse(x, y);

printf("逆順すると%sです。\n", y);

return (0);
}

void reverse(char *moji, char *gyaku)
{
int i, len;

len = strlen(moji);

gyaku = moji + len - 1;

for(i = 0; i < len; i ++){
putchar((int)*gyaku);
...続きを読む

Aベストアンサー

> gyaku = moji + len - 1;

 最終的な gyaku の終端を決めるのに moji は直接関係しません。moji の長さだけです。

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

void reverse( char *moji, char *gyaku )
{
 int len;

 len = strlen( moji );

 gyaku += ( len - 1 ); // moji とは直接関係なし

 while( *moji ){

  *gyaku = *moji;

  putchar( *gyaku );

  gyaku--;
  moji++;
 }
}
void main()
{
 char x[30] = "123456789";
 char y[30] = { 0x00 }; // 初期化

 reverse( x, y );

 printf( " 逆順すると %s です。\n", y );
}
注:インデントに全角空白を用いています。タブに一括変換して下さい。

> gyaku = moji + len - 1;

 最終的な gyaku の終端を決めるのに moji は直接関係しません。moji の長さだけです。

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

void reverse( char *moji, char *gyaku )
{
 int len;

 len = strlen( moji );

 gyaku += ( len - 1 ); // moji とは直接関係なし

 while( *moji ){

  *gyaku = *moji;

  putchar( *gyaku );

  gyaku--;
  moji++;
 }
}
void main()
{
 char x[30] = "123456789";
 char y[30] = { 0x00 };...続きを読む

QC言語で、「自然数nを入力し、nの約数をすべて求めて出力後、その個数と

C言語で、「自然数nを入力し、nの約数をすべて求めて出力後、その個数と合計を出力をする。尚、nとして0(ゼロ)以下が入力されるまで、何度も繰り返す」という問題をやっています。
出力例は、(3を入力したとして)
「3の約数は 1  3
約数の個数は2個
約数の和は4」というものです。

そこで、コーディングをしたのですが、先生が開発したコンパイラで運用したところ、フリーズが起きて強制終了してしまいました。先生は、「そんなことはない。フリーズが起きるときはそのプログラムにバグがあるときだ」と言ってました。

そこでコーディングしたプログラムは以下の通りです。

#include <stdio.h>
main()
{int i,j,n,cnt,sum;
printf("自然数=");scanf("%d",&n);
while(n>=0){
printf("%dの約数は",n);
for(i=1;i<=n;i++){
if(n/i>=0){
j=n/i;
printf(" %d",j);
sum=sum+j;
cnt++;
j=0;}
}
printf("\n");
printf("約数の個数は%d個",cnt);
printf("約数の和は%d",sum);
}}

どこかに間違いがありますか?
IF文の中でいちいちめんどくさいことをしていますが、気にしないでください。

C言語で、「自然数nを入力し、nの約数をすべて求めて出力後、その個数と合計を出力をする。尚、nとして0(ゼロ)以下が入力されるまで、何度も繰り返す」という問題をやっています。
出力例は、(3を入力したとして)
「3の約数は 1  3
約数の個数は2個
約数の和は4」というものです。

そこで、コーディングをしたのですが、先生が開発したコンパイラで運用したところ、フリーズが起きて強制終了してしまいました。先生は、「そんなことはない。フリーズが起きるときはそのプログラムにバグがあるときだ」...続きを読む

Aベストアンサー

少なくともif(n/i>=0)のところはif(n%i==0)の間違いでないかと思います.
しかしそう考えるとjに関する処理は不要なはず.
jに関する処理は約数を逆順にしているだけということになり,質問の
意味と矛盾しますね.
あとj=0;は無駄な処理のように見えます.

QプログラムC言語の整数の約数について教えてください

C言語で整数の約数をすべて表示するプログラムを作りました。
このプログラムの場合、自然数のみ対応し、負の値を入力しても計算されません。
この問いは、このプログラムでも正しいのでしょうか?
それとも負の値を入力しても約数が表示されるようにしなければならないのでしょうか?
その場合どのように直せばよろしいのでしょうか?
ご指導、よろしくお願いします。
#include <stdio.h>

int main()
{
int i;

int n;

printf("整数を入力してください = ");
scanf("%d",&n);

printf("%dの約数は ", n);
for( i=1; i<=n; ++i ){
if( n%i == 0 )
printf("%d ", i);
}
printf("です。\n");

return 0;
}

Aベストアンサー

追加補足です。

処理時間やその他の異常系の考慮をしないで良い前提の回答です。
scanfで数字以外を入力されたらどうするんだ、とか。

n/2よりも大きな約数はn自身しかありえないので、
ループもそこで止めた方が無駄な処理が減らせるとか。

色々考えると改善できる余地はあります。
授業の演習でそこまで求められないと思いますが。

Q指定した文字を削除したい

こんにちは。質問をさせてください。

---------------------------------------------------------------
address = "ここ$http://www.aaaaa.co.jp$moji=dddd$";
---------------------------------------------------------------
変数addressに格納された文字列で、
"http://"の1文字前に"$"があった場合は、
"$"を削除したいのですが、どのようにすれば
いいでしょうか?
※http://の前の"$"以外はそのまま残します。

Aベストアンサー

#include <iostream>
#include <string>

int main() {
std::string address = "ここ$http://www.aaaaa.co.jp$moji=dddd$";
std::string::size_type pos = address.find("$http://");
if ( pos != std::string::npos ) {
address.erase(pos,1);
}
std::cout << address << std::endl;
return 0;
}

Q小松ゼノア(草刈機)G4K-Fの詳細についての質問です。

下記のエンジンのエンジン形式・冷却方式・
点火方式・ボア・ストローク・排気量・作動原理
を教えていただけないでしょうか。

メーカー:小松ゼノア
機種:G4K-F
最大出力:1.62kW(2.2PS)/7,000rpm
最大トルク:2.35Nm(0.24kgfm)/5,000rpm
用途:草刈機

公式のサイトを探してもそれらしきものは見つかりませんでした。
ボア・ストローク・排気量は実際に計測しましたが、
その他は全く想像がつきません。

予想:2サイクルエンジン・空冷・スパーク・?

わかり難いかもしれませんがよろしくお願いします。

Aベストアンサー

PointBlueです。
今日、会社で確認して来た情報によりますと――…

小松ゼノア刈払機/BC430FWに搭載されているエンジンで、
排気量は41.5[cc]
単気筒空冷式
使用プラグはNGKのBPM6A
点火方式はCDI
始動方式はリコイルスタータ方式
燃料タンク容量は1.1[リットル]
燃料は1:25(2stオイル:ガソリン)混合燃料(推奨)
キャブレタ型式はG13P-1E
アイドリング回転数:2100~2300[rpm]
使用回転数:3000~10000[rpm]
無負荷最高回転数:12000以下[rpm]

…――との事でありました。
富士ロビン製エンジンと混同しておりました。
訂正してお詫び申し上げます。


人気Q&Aランキング