0

I need a bit of guidance.

I want to sharpen my skill, so I'm practicing with smaller projects.

The current challenge is to create a function that can count syllables in a user inputted word.

My thinking is to declare an array of vowels: a, e, i, o, u.

then iterate through the user inputted word, checking if any letters of the word match with the vowel array, and if yes, check if the next letter doesn't. (I'm assuming a syllable is defined by the presence of a vowel AND consonant.)

This will need nested for loops, one to iterate through the word, and then another to iterate through the vowel array with the current index of 'word'.

I haven't even figured out how I'm going to do the same for word[i+1] yet.

But I'm struggling because I can't get my program to compile due to basic errors. I should probably use a string class, but I don't know.

Here's what I've got (And it won't compile!):

#include <iostream>

char vowels[] = {'a', 'e', 'i', 'o', 'u'};

int numberOfSyllables(char *word)
{
    int numberOfVowelsFound = 0;

    for ( &element : word )
    {
        bool vowelMatch = 0;
        for ( &vowel : vowels)
        {
            if (element == vowel)
            {
                vowelMatch = 1;
                break;
            }
        }
    if ((vowelMatch == 1) numberOfVowelsFound++;
    }
    return numberOfVowelsFound;
}


int main()
{
char *userInput[50];

std::cout << "Enter a word: ";
std::cin >> *userInput;

std::cout << numberOfSyllables(userInput) << " syllables found";

    return 0;
}
aName
  • 257
  • 2
  • 8
  • https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – πάντα ῥεῖ Apr 18 '19 at 20:33
  • Related logic in C [Counting Syllables in an Array](https://stackoverflow.com/questions/54624166/counting-syllables-in-an-array/54625588?r=SearchResults&s=1|56.5469#54625588) – David C. Rankin Apr 18 '19 at 20:46
  • 1
    C/C++ are very hard to learn if you don't understand what you're looking at. If this is your first language, you are better off learning something else first. – yyny Apr 18 '19 at 20:46
  • 2
    No. You are better off learning the language you are working with. All things considered, C provides in irreplaceable foundation for whatever language you end up writing in. Understanding memory use at the byte-level will make you a better programmer regardless what language you ultimately end up using. (most being written in C/C++ anyway) – David C. Rankin Apr 18 '19 at 20:48
  • 1
    Understanding exactly what your programs are doing is crucial in becoming a better programmer and to be able to work on bigger projects, but it over-complicates the learning experience when starting off, because you need to learn many more skills at once to be able to advance. The asker made many mistakes in this simple program, most of which are avoided by switching to a more beginner-friendly programming language. I think C is not the worst language to learn as a beginner, but both C and C++ really over-complicates a lot of things that are very simple in other languages. – yyny Apr 18 '19 at 21:00

1 Answers1

4

This is not a code review website, but I will try my best anyway:

  1. Your for loops don't have types:
    for (TYPE &element : word )

The type you want to loop over in this case is char.

if you wanted the compiler to figure out the type for you:

    for (auto &element : word)
  1. You are looping over word with a "foreach" style loop, but a char * cannot be looped over this way. To be precise, there is no std::begin and std::end functions defined for char *, so the "foreach" style loop doesn't know where you want your string to begin/end. Either use a different style of loop, or use a type that does support "foreach" style loops (such as std::string or C++17's std::string_view).

  2. You added an extra parenthesis ( in the if statement:

    //  |
    //  v
    if ((vowelMatch == 1) numberOfVowelsFound++;
  1. You declare your userInput variable as an "array of 40 pointers to characters", but you probably want to write "characters" to it, not "pointers to characters". Change it's type to "array of 40 characters".

  2. Similarly, you dereference your userInput variable (probably to avoid a warning), which, because userInput is an "array of 40 (pointers to char)", will return the first, uninitialized, "pointer to char" in that array (*var is the same as var[0] in this case). Just remove the dereference operator * and change the type of the array as suggested above, and std::cin will figure out what to do. Because you (wrongfully) dereferenced userInput already to avoid a warning, std::cin thinks you want to write to the location pointed to by the uninitialized pointer. You have no control over where your program will write too at this point; it might simply crash.

  3. Finally, you once again pass the wrong type into numberOfSyllables(userInput), as mentioned before, userInput is an "array of 40 pointers to char", while your function expects a "pointer of chars". Change the type of userInput to "array of chars", which the compiler can then convert to "pointer of chars".

Final code:

// compile with -std=c++17 for std::string_view, or use another loop style
#include <string_view>
#include <iostream>

char vowels[] = {'a', 'e', 'i', 'o', 'u'};

int numberOfSyllables(char *word)
{
    int numberOfVowelsFound = 0;

    // `std::string_view` can be used in "foreach" style loops
    // we need to use `const char`, since `std::string_view` is a "fake string" and not writable
    for (const char &element : std::string_view(word))
    // Another loop style (This even works in C):
    // for (int i=0; word[i] != '\0'; i++) // While the current element is not NUL
    // {
    //     const char element = word[i]; // Remember the current element
    {
        bool vowelMatch = 0;
        for (const char &vowel : vowels) // Use const here too just for good measure
        {
            if (element == vowel)
            {
                vowelMatch = 1;
                break;
            }
        }
        if (vowelMatch == 1) numberOfVowelsFound++; // Removed a parenthesis here
    }
    return numberOfVowelsFound;
}


int main()
{
    char userInput[50]; // Changed type of this variable

    std::cout << "Enter a word: ";
    std::cin >> userInput; // Removed a dereference here
    std::cout << numberOfSyllables(userInput) << " syllables found";

    return 0;
}
yyny
  • 1,623
  • 18
  • 20
  • 2
    An addendum to point 2: `char *` is a pointer to a `char`. All it knows is where to find a `char`. There could be more `char`s after the first, but a pointer does not know that. This makes stuff like `std::end` impossible because there is no way to tell from a pointer where the end is. If you are given a `char *` and you need to know where it ends, you have two possibilities: A) Along with the `char *`, you were provided a length or – user4581301 Apr 18 '19 at 21:48
  • 1
    B) the last character of significance in the storage pointed at by the `char *` has been terminated with a character that cannot exist in the sequence of characters, usually a null (`'\0'`). – user4581301 Apr 18 '19 at 21:48
  • This is amazing. Thank you so much. I spent the last month trying to learn/understand pointers, and so I overlooked that I may be over-complicating the code. I removed the pointers and turned every `char` into `string`, fixed the foreach loops, removed the stupid extra bracket, and BOOM! Later today I will take look at your code (thank you for the excellent comments) to see how to work with chars again in the future. Sorry, I know this isn't a code review site, but I had nowhere else to go! – aName Apr 19 '19 at 09:52