2016-07-30 4 views
1

Я пытаюсь создать программу, которая подсчитывает гласные в строке. Когда печатается гласнаяInString, все значения остаются на нуле.Невозможно добавить в целое число в массив

#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]); 
    } 
} 

Похоже, что это не соответствует утверждению if на линии 20. Почему?

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

Как вы думаете, насколько велика 'stringToTest []', если вы не указали размер и использовали пустой инициализатор? Кроме того, '% c' сообщает' scanf() 'читать * один символ' char' *, а не строку. – Dmitri

+0

Вы можете найти, что 'vowels'' 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 вместо правильного < «работает» случайно, потому что размер вашего массива равен пяти. Вы должны передать размер от 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; ...' позже. –

Смежные вопросы