2016-07-30 67 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; ...)。 –