2016-07-30 6 views
1

文字列の母音を数えるプログラムを作成しようとしています。 vowelsInStringが出力されると、すべての値はゼロのままです。配列に整数を追加できません

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

void printfArray(int array[]); 

int main() 
{ 
    char stringToTest[] = {}, vowels[5] = {'a', 'e', 'i', 'o', 'u'}; 
    int i, j, numOfVowels, vowelsInString[5] = {0, 0, 0, 0, 0}; 

    numOfVowels = 0; 

    printf("Enter: "); 
    scanf("%c", &stringToTest); 

    for(i=0; i<sizeof(stringToTest); i++) 
    { 
     for(j=0; j<sizeof(vowels); j++) 
     { 
      if(stringToTest[i] == vowels[j]) 
      { 
       numOfVowels++; 
       vowelsInString[j]++; 
       printf("%d",vowelsInString[j]); 
      } 
     } 
    } 

    printfArray(vowelsInString); 
} 

void printfArray(int array[]) 
{ 
    int i; 

    for(i=0; i<=sizeof(array); i++) 
    { 
     printf("%d\n", array[i]); 
    } 
} 

20行目のif文に適合しないようです。なぜですか?

char stringToTest[] = {}; // This is not standard C 

この宣言は、長さゼロの配列を作成し、Cの拡張機能である:

if(stringToTest[i] == vowels[j]) 
+2

サイズを指定せずに空のイニシャライザを使用した場合、 'stringToTest []'はどれくらい大きいと思いますか?また、 '%c'は' scanf() 'に文字列ではなく単一の' char' *を読み込ませるよう指示します。 – Dmitri

+0

'' enow''を '母音'にするともっと簡単になります。 'string.h'関数を使うことができれば、*ポインタ*と' strpbrk'を使うことも魅力的かもしれません。 –

答えて

2

プログラムが動作しない理由は、あなたがstringToTestを宣言する方法です。後でそのサイズを取ると、ゼロ(demo)になるので、プログラムは決してループに入りません。

char stringToTest[100]; 
... 
scanf("%99s", stringToTest); 

使用strlen代わりsizeofのエンドユーザーが入力した単語の実際の長さを取得するには::、この問題を解決するいくつかの最大サイズにstringToTestを割り当て、そして%sの代わり%cを読むには

size_t len = strlen(stringToTest); 
for(i=0; i<len; i++) 
    ... 

printfArrayも修正が必要です。sizeof(array)はシステム上のポインタのサイズを返します。あなたがしようとしたように "固定"して、<の代わりにforループの<=を使用して、配列のサイズが5であるため "うまく"動作します。あなたはこのように、mainからサイズを渡しする必要があります。

void printfArray(int array[], size_t len) { 
    for (size_t i = 0 ; i != len ; i++) { 
     ... 
    } 
} 
+0

'char stringToTest [] = {}'は標準Cでは使用できません( 'sizeof'は' 0')。あなたがデモする動作は、コンパイラの拡張機能になります。 –

0

あなたはすでにあなたが定数として母音を定義することを考慮した場合に作りながら、あなたのコードビットを短縮することが、あなたの当面の問題に非常に良い答えを持っているので、プロセスは少し読みやすくなります。テストする配列で母音を保持することには何も問題はありませんが、母音を定数として指定し、短い子音であるswitchを指定することで別のアプローチができます。 (あなたは望むなら大文字/小文字の母音を分離して追跡することができます)。 (文字列が指定されていない場合、デフォルトの一例として"alligator")最初の引数としてテストする文字列を受け取り、迅速な代替実装は次のようになります。ただ、

#include <stdio.h> 

enum { a, e, i, o, u }; /* these become global constants, don't reuse */ 

int main (int argc, char **argv) { 

    char *st = argc > 1 ? argv[1] : "alligator", *p = st; 
    unsigned vowels[5] = {0}, sum = 0; 

    for (; *p; p++) { /* for each char in st, convert to lower */ 
     char c = ('A' <= *p && *p <= 'Z') ? *p | (1 << 5) : *p; 
     switch (c) { 
      case 'a' : vowels[a]++; break; /* increment vowels */ 
      case 'e' : vowels[e]++; break; 
      case 'i' : vowels[i]++; break; 
      case 'o' : vowels[o]++; break; 
      case 'u' : vowels[u]++; break; 
     } 
    } 
    /* get total and print */ 
    sum = vowels[a] + vowels[e] + vowels[i] + vowels[o] + vowels[u]; 
    printf ("\n vowels in '%s'\n\n a or A : %2u\n e or E : %2u\n i or I : %2u\n" 
      " o or O : %2u\n u or U : %2u\n -----------\n total %2u\n", st, 
      vowels[a], vowels[e], vowels[i], vowels[o], vowels[u], sum); 

    return 0; 
} 

使用例/出力

$ ./bin/vc "The quick brown fox jumps over a lazy dog." 

vowels in 'The quick brown fox jumps over a lazy dog.' 

a or A : 2 
e or E : 2 
i or I : 1 
o or O : 4 
u or U : 2 
----------- 
    total 11 

別の方法でskin-the-cat。あなたが何か質問がある場合はそれを見て、私に知らせてください。

+0

一般的に、私は列挙メンバのための単一の文字の名前をお勧めしません... – Dmitri

+0

はい、私はそれが右にコメントを置く理由を見ました。あなたは確かに 'for(int i = 0; ...')を必要としません。 –

関連する問題