Counting syllables in a word C++ - c++

I have created a program to count the syllables in a word inputted by the user. The user is to enter any amount of words followed by the enter key until the (#) key is entered, then the program is to display the words in a table followed by the syllable count for each word.
I am having issues with the "silent e" portion of my program.
if (word_length - 1 == 'e')
{
vowels = vowels - 1;
It seems as though it is not able to pick up the last letter in the string of words. I have tried to move some of the if statements around to see if that helps and to better identify where the problem lies, and from what I have noticed, as stated earlier i believe it to be with the silent e portion of the code.
It is difficult to find even the smallest errors in my code, so I am asking for another set of eyes to gaze over my code.
Any help will be greatly appreciated.
Also, I have yet to complete the formatting of my results table, so please over look that.
#include <iostream>
#include <string>
#include <iomanip>
#include <vector>
using namespace std;
int main()
{
string word_1 = "create list";
int vowels = 0;
int word_length; // better to set .length() into variable to eliminate warnings
int words_to_print = 0; // this will count how many words to print to use in for loop later
/*
vector <variable type> name_of_vector[size of vector];
creating vectors
leaving them empty for now
*/
vector <string> words_saved;
vector <int> number_of_syllables_saved;
cout << "Enter 4 words from the English dictionary, to determine the amount of syllables each word has." << endl;
cout << "Please enter [#] when finished, to create a list." << endl;
cin >> word_1;
while (word_1 != "#") // as long as user doesnt enter # you can enter a word and
{ // have it run thru the syllable logic
word_length = word_1.length();
words_to_print++;
words_saved.push_back(word_1);
// ^ this saves the word into the next availabe index of vector for strings.
for (int i = 0; i < word_length ; i++) // length is a variable now instead of function syntax this
{ // eliminates the <: signed/usnsigned mismatch warning below
if ((word_1[i] == 'a') || (word_1[i] == 'e') || (word_1[i] == 'i') || (word_1[i] == 'o') || (word_1[i] == 'u') || (word_1[i] == 'y'))
{
vowels = vowels + 1;
if ((word_1[i + 1] == 'a') || (word_1[i + 1] == 'e') || (word_1[i + 1] == 'i') || (word_1[i + 1] == 'o') || (word_1[i + 1] == 'u') || (word_1[i + 1] == 'y'))
{
vowels = vowels - 1;
if (word_length - 1 == 'e')
{
vowels = vowels - 1;
if (vowels == 0)
{
vowels = vowels + 1;
}
}
}
}
}
number_of_syllables_saved.push_back(vowels);
//^ this puts number of syllables into vector of ints
vowels = 0; // this resets the amounts so it can count vowels of next word and not stack from previous word
cin >> word_1; // this will reset the word and controls loop to print out chart if # is entered
}
// use a for loop to print out all the words
cout << endl << endl << endl;
cout << "Word: " << setw(30) << "Syllables: " << endl;
for (int x = 0; x < words_to_print; x++)
{
cout << words_saved[x] << setw(20) << number_of_syllables_saved[x] << endl;
}
//system("pause");
return 0;
}

You are comparing the character 'e' to the integer word_length - 1 instead of comparing it to the last character of your string as you intended.
You should replace if (word_length - 1 == 'e') with if (word_1[word_length - 1] == 'e').

Your nested if-statements don't get evaluated at the anticipated index.
Say the input is "state".
At i = 0, word_1[i] = 's', doesn't pass the first if statement.
At i = 1, word_1[i] = 't', doesn't pass the first if statement.
At i = 2, word_1[i] = 'a', vowels becomes 1. The program does not proceed further down the nested if statements since word_1[i+1] is 't'.
At i = 3, word_1[i] = 't', doesn't pass the first if statement.
At i = 4, word_1[i] = 'e', vowels becomes 2. The program does not proceed further down the nested if statements since word_1[i+1] is garbage value.
As you can see, it never reaches the nested if-statements as you intended

Related

Program for getting amount of words that start with Vowels and Consenants is returning wrong answers

Im writing a program for class and so far i have the word counter working fine and the vowel part working fine but Consonants and non alpha digits return wrong answers by 1(in certain cases). i think the problem lies in the testing of the characters them selves but i cant seem to find a way around it.
using namespace std;
int main()
{
char ch;
int count = 0;
int vowel = 0;
int cons = 0;
int noalph = 0;
bool inword = 1;
bool space = 0;
while (cin.get(ch)) {
if (ch != ' ') {
inword = 1;
}
if (isspace(ch)) {
space = 1;
}
else if (space && inword) {
count++;
space = 0;
inword = 0;
if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' ||
ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U' ||
ch == 'y' || ch == 'Y') {
vowel++;
}
if (ch != 'a' && ch != 'e' && ch != 'i' && ch != 'o' && ch != 'u' &&
ch != 'A' && ch != 'E' && ch != 'I' && ch != 'O' && ch != 'U' &&
ch != 'y' && ch != 'Y'
&& isalpha(ch)) {
cons++;
}
if (ispunct(ch) || isdigit(ch)) {
noalph++;
}
}
}
if (count > 0) {
count++;
}
//--------------------------------------------
cout << "Total Number of Words = " << count << endl;
cout << "Number of Words Beginning with a Vowel = " << vowel << endl;
cout << "Number of Words Beginning with a Consonant = " << cons << endl;
cout << "Number of Words Beginning with a Non-Alpha = " << noalph << endl;
return 0;
}
Example 1(
Input:--------------------------------------------------------------------
supercalifragilisticexpialidocious
A nonsense-word used esp. by children, now chiefly expressing excited
approbation: fantastic, fabulous.
Made popular by the Walt Disney film "Mary Poppins" in 1964. The
song containing the word was the subject of a copyright infringement
suit brought in 1965 against the makers of the film by Life Music
Co. and two song-writers: cf. quots. 1949, 1951. In view of earlier
oral uses of the word sworn to in affidavits and dissimilarity between
the songs the judge ruled against the plaintiffs.
Taken from the OED.
Output:--------------------------------------------------------------------
Total Number of Words = 86
Number of Words Beginning with a Vowel = 25
Number of Words Beginning with a Consonant = 55
Number of Words Beginning with a Non-Alpha = 5
Expected:------------------------------------------------------------------
Total Number of Words = 86
Number of Words Beginning with a Vowel = 25
Number of Words Beginning with a Consonant = 56
Number of Words Beginning with a Non-Alpha = 5
)
Example 2(
Input:--------------------------------------------------------------------
1996
bottle
12345
radar
a Toyota
Madam, I'm Adam
Was it a rat I saw?
Norma is as selfless as I am, Ron.
A man, a plan, a canal--Panama!
Tarzan raised Desi Arnaz' rat.
Hannah
Lewd did I live, & evil I did dwel.
Excerpts from "The Zen of Programming"
Mary said, "I like the STL."
Output:--------------------------------------------------------------------
Total Number of Words = 56
Number of Words Beginning with a Vowel = 20
Number of Words Beginning with a Consonant = 31
Number of Words Beginning with a Non-Alpha = 4
Expected:------------------------------------------------------------------
Total Number of Words = 56
Number of Words Beginning with a Vowel = 20
Number of Words Beginning with a Consonant = 31
Number of Words Beginning with a Non-Alpha = 5
)
As you can see it breaks at different points, maybe its something simple maybe it not, i would just like some help understanding what is going on, Thank You!
OK, you didn't followed advices in comments, so let do it explicitly.
You are skipping the first word.
Cause of the initialization in this line:
bool space = 0;
you should initialize it as true
bool space = true;
(yes, use true and false for boolean).
you should see that cause you added this lines
if (count > 0) {
count++;
}
to cover this problem. So, remove them.
You also skipped the #include <iostream> directive.

Testing word is in language L = {a^n-1b^n} using stack

I am writing a C++ function that implements a stack to test if a word is in language L = {a^n-1b^n}. Words that exist include b, abb, aabbb.
I have seen many postings with regards to testing a word being in a language where L = {a^nb^n} and I am just wondering how to go about this when the n's are not equal.
The code that I have written works but I feel that I am taking the easy way out with regards to making sure the word is not in a format like aba bababa abababa etc. I have implemented this test outside of the stack but feel there should be a way to do it in the stack.
The reason I say this is because I later have to take the function bool isInLanguageL(string w) and use the following header instead bool isInLanguageL(queueType &w). I have been having trouble trying to convert the code I previously had with string w to queue w.
//function prototype
bool isInLanguageL(string w);
//function to see if the word exists in the language
bool isInLanguageL(string w) {
//creating counters for the a's and b's
int countPush = 0;
int countPop = 0;
reverse(w.begin(), w.end()); //putting the b's infront
//creating the charachter stack
stack<char> charStack;
//checking the word for an illegal format such as aba or bab
for (int i = 0; i < w.length(); i++) {
if ((w[i] == 'a' && w[i + 1] == 'b' && w[i+2] == 'a') || (w[i] == 'b' && w[i + 1] == 'a' && w[i + 2] == 'b')) {
cout << "This is an illegal format of a word in language L and therefore: ";
return false;
}
else { //if the word is a legal format then continue onto stack creation
//adding the b's to the stack and counting them simultaneously
if (w[i] == 'b') {
charStack.push(w[i]);
countPush++;
}
//popping off the stack everytime there is an a and counting simultaneously
else if (w[i] == 'a') {
charStack.pop();
countPop++;
}
}
}
//if the stack is not empty and a = b-1 then the word exists
if (!charStack.empty() && countPop == (countPush - 1))
return true;
else
return false;
}
int main() {
//introduction
cout << "The language rule is L = {a^n-1b^n}" << endl;
//creating an empty string for the word and condition variable for exit
string word = " ";
int exit = 0;
while (exit == 0) {
//getting word from the user
cout << "\nWord: ";
cin >> word;
//calling function to check if word exists in L
if (isInLanguageL(word)) {
cout << "The word exists in language L" << endl << endl;
}
else
cout << "The word doesn't exist in language L" << endl << endl;;
cout << "Would you like to exit (1-yes/0-no): ";
cin >> exit;
}
system("pause");
return 0;
}
If anyone can just lead me in the right direction with regards to testing for whether the word is of a legal format (not aba abababa bababa), it would be greatly appreciated.

debugging c++ program with <set> containers

The problem is to find all vowels all even words in a sentence share, in other words these vowels have to be met in any even word in the sentence.
But i when i enter for example: "ewedyua aiuye dswidje ieuayj eeee eeeui dajhdfjcne aodijsbfe".
I get: e i u
but "e i" is expected as the last even word doesn't contain 'u' (I use " " just for separation here in the text and don't use them in the output)
The program:
int main(){
string str;
char ch = ' ';
set<char> strSet;
set<char> resultSet;
set<char> tempSet;
int count = 1;
int i = 0;
cout << "Enter a line: ";
getline(cin, str);
str = delOverSpace(str); // delete excessive gaps<br>
do {
ch = str.at(i);
if(((count % 2) == 0) && (ch != ' ')){ // this is an even word and not a gap
if(isVowel(upperToLower(ch))) // this is a vowel
tempSet.insert(upperToLower(ch));
}
if (ch == ' ') { // if we've passed through the word add inforamtion on it
if(((count % 2) == 0) && (count / 2) == 1)
strSet.insert(tempSet.begin(), tempSet.end());
else if (((count % 2) == 0) && (count / 2) != 1){
set_intersection(
strSet.begin(),strSet.end(), tempSet.begin(), tempSet.end(),
insert_iterator<set<char> >(resultSet, resultSet.begin())
);
strSet.clear();
tempSet.clear();
strSet.insert(resultSet.begin(), resultSet.end());
resultSet.clear();
}
count++;
}
i++;
}while(ch != '.');
if (count == 2) cout << "Only one word was entered" << endl;
else if (strSet.empty()) cout << "No vowels were found" << endl;
else {
copy(strSet.begin(), strSet.end(), ostream_iterator<char>(cout, " "));
cout << endl;
}
return 0;
}
Try not to use one counter variable for multiple purposes.
For example you could use count for the current character count within the current word and words for word count.
In your example, you're making count work too hard.
Decide what you are counting. Do you want to count every character?
Or do you want to count the characters in the current word?
When incrementing a counter, try to put this next to the logic that needs it.
Eg, i++ should go right after you've used it to get the next character.
And count should be incremented in the block that handles letters (ie not space, not dot).
If the counters get too far away from what they are keeping track of, you can introduce bugs.
Move the space check up first and also check for end of sentence with .
Clear indentation helps to follow the code - I use 4 characters, but 2 or 3 is ok.
1 character indents are hard to read.
Use blank lines to separate different chunks of logic.
You might want to add logic to handle punctuation like ,, ?, ! etc.
When you're processing an input string which is separated into words, it's often easier to handle the end of input condition outside the loop.
In this case, the loop exits after it picks up the last letter.
If that is not a . then you'll have an unprocessed word sitting in tempSet.
You can try and anticipate this within the loop, but it seems more natural to exit the loop and check if there is anything left to process.
If you separate your logic into clearly separated blocks, you can set breakpoints inside each block.
You'll then know what situation you're handling. You can break inside end-of-word logic and check tempSet and count.
Are they what you expect?
And in the else part you can check ch going in and verify that it is classified as a vowel properly.
int main() {
string str;
char ch = ' ';
set<char> strSet;
set<char> tempSet;
int count = 0, words = 0, i = 0;
cout << "Enter a line: ";
getline(cin, str);
str = delOverSpace(str); // delete excessive gaps<br>
while ( i < str.size() && ch != '.' ) {
// Get next character
ch = str.at(i);
i++;
if (ch == ' ' || ch == '.' ) { // if we've passed through the word add inforamtion on it
if( count > 0 && ((count % 2) == 0)) {
strSet.insert(tempSet.begin(), tempSet.end());
words++;
}
count = 0; // reset the char counter
tempSet.clear(); // clear the temp vowel set
}
else {
// letter - not a space or a dot, increase the character count
count++;
if(isVowel(upperToLower(ch))) // this is a vowel
tempSet.insert(upperToLower(ch));
}
}
// pick up any unprocessed word if we hit end of input without seeing '.'
if (count > 0 && ((count % 2) == 0)) {
strSet.insert(tempSet.begin(), tempSet.end());
words++;
}
if (words == 0)
cout << "No words entered" << endl;
else if (words == 1)
cout << "Only one word was entered" << endl;
else if (strSet.empty())
cout << "No vowels were found" << endl;
else {
copy(strSet.begin(), strSet.end(), ostream_iterator<char>(cout, " "));
cout << endl;
}
return 0;
}

What is wrong with this Pig Latin program?

What it's supposed to do
My piglatin program is supposed to take a phrase from user input and output it into pig latin. Basically it would turn a word such as "hello" into "ellohay".
My problem
When I input hello my man the output is ellohay y man an may and when I just input hello my the output is ellohay y may. As you can see, after it translates the first word successfully, it struggles on the second word. It places a space after the y and mayI cannot figure out for the life of me why this keeps happening. The output is even stranger when I input more than two words, as shown above. What I want to happen is for it to output ellohay ymay anmay when I input hello my man. Code is below. Thanks!
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
void phrase_Parser(string); // Goes through phrase and looks for ' ' to then pass to pigLatin_Translator()
void pigLatin_Translator(string);
int main()
{
string phrase; //used for user word or phrase to be translated to piglatin
cout << "Enter any word: ";
getline(cin, phrase);
phrase_Parser(phrase);
return 0;
}
void phrase_Parser(string phrase) {
int startCount = 0;
for (int i = 0; i < phrase.length(); i++) {
if (phrase[i] == ' ') {
string word = phrase.substr(startCount, i);
startCount = (i + 1); // decides where to start the word next time it is ran through
pigLatin_Translator(word); // runs word through translator
}
}
}
void pigLatin_Translator(string word) {
string partOne;
string partTwo;
for (int x = 0; x < word.length(); x++) {
if (word[0] == 'q' && word[1] == 'u') {
cout << word.substr(2, word.length()) << word.substr(0, 2) << "ay ";
break;
}
else if ((word[x] == 'a') || (word[x] == 'e') || (word[x] == 'i') || (word[x] == 'o') || (word[x] == 'u') || (word[x] == 'y')) {
partOne = word.substr(x, word.length()); //from first vowel to end of word
partTwo = word.substr(0, x); // from first letter to first vowel, not including the vowel
cout << partOne << partTwo << "ay "; // adding "ay" to the end of the word
break;
}
}
}
Your problem is in the line string word = phrase.substr(startCount, i);
You are using substr incorrectly. The second argument to substr is the length of the substring you wish to extract. Replace i with i-startCount and you should be good to go.
Alternatively, search for a nicer way to split strings. There are a number of options that are much easier than doing it manually.

String with an interchangeable letter

The directions for my assignment are as follows:
Return the number of times that the string "hope" appears anywhere in the given string, except we'll accept any letter for the 'p', so "hode" and "hooe" count.
I am struggling to figure out how to make the third letter equal anything and still have the program identify that it is correct.
My code so far is quite obviously wrong but ill include it nonetheless.
one big problem is i can't tell the array to check if it matches the string.
int wordsFunction(string words)
{
int num = 0;
for(int i = 0; i < words.length(); i++)
{
if(words[i] == "Hope" || words[i] == "hope")
{
num++;
}
}
return num;
}
main()
{
string words;
cout << "Enter a string: ";
getline(cin, words);
cout << wordsFunction(words);
My code so far is quite obviously wrong
That is true. I wouldn't explain why your code is wrong, and go straight to a description of a fix.
Your main reads the string that allows spaces, which is good: the I/O part of your code does not need to be changed.
Now observe that to detect the word "ho*e", with * denoting any single character, at a position i in a word w, you need to check that w[i] is an 'h', w[i+1] is an 'o', w[i+3] is an 'e', and that the index i+3 is valid. This becomes a simple check:
if (i+3 < w.size() && w[i] == 'h' && w[i+1] == 'o' && w[i+3] == 'e') {
count++;
}