2016-07-30 69 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語句。爲什麼?

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

考慮到您沒有指定大小並使用空初始化程序,您認爲'stringToTest []'有多大?此外,'%c'告訴'scanf()'讀*一個'char' *,而不是一個字符串。 – Dmitri

+0

你可能會發現把元音變成'enum'可以讓生活更簡單。如果你可以使用'string.h'函數,使用幾個*指針*和'strpbrk'也可能很有吸引力。 –

回答

2

程序爲何不工作的原因是您聲明stringToTest方式:

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

這聲明是一個C擴展,創建一個零長度的數組。當你稍後取得它的大小時,你得到零(demo),所以程序永遠不會進入循環。

爲了解決這個問題,分配stringToTest一些最大尺寸,並與%s代替%c閱讀:

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

使用strlen代替sizeof獲得由最終用戶輸入的單詞的實際長度:

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

標準C中不允許使用char stringToTest [] = {}'(其中沒有任何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

一般來說,我不會爲enum成員推薦單個字符名稱...... – Dmitri

+0

是的,我看到了這一點,這就是爲什麼我把註釋放在右邊。你肯定不想在以後使用for(int i = 0; ...)。 –