-1

I am trying to write a program that will count the number of words, and number of sentences, and then take the average of those sentences. It takes the input from a user and will stop taking the input upon seeing "@@@". My code is as follows:

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <string>
using namespace std;

int main() ///Main
{

    //1. Declaration of variables

    string text;
    double word_count = 0.0;
    double sentence_count = 0.0;
    double avg_words_per_sentence;

    //2. Prompt user input

    cout << "Enter a paragraph..." << endl;
    getline(cin, text, '@'); //3. Use getline to read whole paragraph and not first word entered

    //4. Loop to read through text inputted and determine number of words and sentences

    for (int i = 0; i < text.length(); i++) 
    {
        if (text[i] == ' ')
        {
            word_count++;
        }
        
        else if (text[i] == '.' || text[i] == '!' || text[i] == '?') 
        {
            sentence_count++;
        }
    }
    
    //5. Provides error if there is no text

    if (word_count == 0 && sentence_count == 0) 
    {
        cout << "Word count: " << word_count << endl;
        cout << "Sentence count: " << sentence_count << endl;
        cout << "You did not enter any text!" << endl;
    }
    
    //6. Provides an error if there are no sentences 

    else if (sentence_count == 0) 
    {
        cout << "Word count: " << word_count + 1 << endl;
        cout << "Sentence count: " << sentence_count << endl;
        cout << "You did not enter any sentences!" << endl;
    }
    
    //7. Calculates and outputs word/sentence count and average # of words

    else 
    {
        word_count++;
        avg_words_per_sentence = word_count / sentence_count;
        cout << "Word count: " << word_count << endl;
        cout << "Sentence count: " << sentence_count << endl;
        cout << "Average words per sentence: " << fixed << setprecision(1) << avg_words_per_sentence << endl;
    }

    return 0;
}

For example: If I were to use the input:

ttt

@@@

I would expect my word count to be 1, but I am instead told that it is 2. I am unsure as to why it is counting 2.

I tried tweaking certain if/then statements such as if the string contain "@" to not count the word or only count words if there is a space after a proper character but I am still met with the same incorrect number of words

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
  • 1
    For that input, I get `Word count: 0` `Sentence count: 0` `You did not enter any text!` - there are no spaces in `ttt\n` so how can you get `2` words? – Ted Lyngmo Feb 15 '23 at 19:21
  • What is the rationale for `word_count++;` in the else clause (section 7)? – Avi Berger Feb 15 '23 at 19:24
  • You'll be glad to hear you don't need anyone's help to figure this out, just a tool you already have: your debugger! This is exactly what a debugger is for. It [runs your program, one line at a time, and shows you what's happening](https://stackoverflow.com/questions/25385173/), this is something that's every C++ developer must know how to do. With your debugger's help you'll able to quickly find all problems in this and all future programs you write, without having to ask anyone for help. Have you tried using your debugger, already? If not, why not? What did your debugger show you? – Sam Varshavchik Feb 15 '23 at 19:28
  • 1
    Sentences like _"I noticed that 5! = 120."_ and _"I jumped 5.5 meters."_ may cause problems for the counting algorithm. – Ted Lyngmo Feb 15 '23 at 19:47

1 Answers1

0

For starters, you have no need to store word and sentence counts as doubles, and this will cause you problems later in your comparisons for conditions: if (word_count == 0 && sentence_count == 0) should never be done for non integer types.

Your other 'issue' is your own doing, you have 3 cases at the end:

    if (word_count == 0 && sentence_count == 0) 
    {
        cout << "Word count: " << word_count << endl;
        cout << "Sentence count: " << sentence_count << endl;
        cout << "You did not enter any text!" << endl;
    }

All is as expected (assuming word_count and sentence_count are not floating point)

    else if (sentence_count == 0) 
    {
        cout << "Word count: " << word_count + 1 << endl;
        cout << "Sentence count: " << sentence_count << endl;
        cout << "You did not enter any sentences!" << endl;
    }

When sentence count is 0 but word count is not, you add 1 to the number of words counted. This is what is causing the 'issue' you have described. You do something similar with:

    else 
    {
        word_count++;
        avg_words_per_sentence = word_count / sentence_count;
        cout << "Word count: " << word_count << endl;
        cout << "Sentence count: " << sentence_count << endl;
        cout << "Average words per sentence: " << fixed << setprecision(1) << avg_words_per_sentence << endl;
    }

By adding 1 to word count when you get a nonzero word/sentence count.

I see your intention there, but I think to get your desired behavior, you would just want to account for a word without punctuation as I have added, get rid of the random +1 to word counts, and use integers for comparison as such:

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <string>
using namespace std;

int main() ///Main
{

    //1. Declaration of variables

    string text;
    int word_count = 0;
    int sentence_count = 0;
    double avg_words_per_sentence;

    //2. Prompt user input

    cout << "Enter a paragraph..." << endl;
    getline(cin, text, '@'); //3. Use getline to read whole paragraph and not first word entered

    //4. Loop to read through text inputted and determine number of words and sentences

    for (int i = 0; i < text.length(); i++) 
    {
        if (text[i] == ' '|| text[i] == '\n')
        {
            word_count++;
        }
        
        else if (text[i] == '.' || text[i] == '!' || text[i] == '?') 
        {
            sentence_count++;
        }
    }
    
    //5. Provides error if there is no text

    if (word_count == 0 && sentence_count == 0) 
    {
        cout << "Word count: " << word_count << endl;
        cout << "Sentence count: " << sentence_count << endl;
        cout << "You did not enter any text!" << endl;
    }
    
    //6. Provides an error if there are no sentences 

    else if (sentence_count == 0) 
    {
        cout << "Word count: " << word_count << endl;
        cout << "Sentence count: " << sentence_count << endl;
        cout << "You did not enter any sentences!" << endl;
    }
    
    //7. Calculates and outputs word/sentence count and average # of words

    else 
    {
        avg_words_per_sentence = word_count / sentence_count;
        cout << "Word count: " << word_count << endl;
        cout << "Sentence count: " << sentence_count << endl;
        cout << "Average words per sentence: " << fixed << setprecision(1) << avg_words_per_sentence << endl;
    }

    return 0;
}

Note that this is still not a perfect approach, as multiple newlines will be counted as words. For anything more advanced, you may want to look into a state machine type approach (keep track of if you have encountered a character before newlines and only count words then, for example). Some sample output from this version is below:

Enter a paragraph...
ttt
@@@
Word count: 1
Sentence count: 0
You did not enter any sentences!
Enter a paragraph...
ttt hehehe.
@@@
Word count: 2
Sentence count: 1
Average words per sentence: 2.0
Enter a paragraph...
ttt heheh
@@@
Word count: 2
Sentence count: 0
You did not enter any sentences!
Enter a paragraph...


@@@
Word count: 2
Sentence count: 0
You did not enter any sentences!
Douglas B
  • 585
  • 2
  • 13
  • Added testcase: `ttt@@@` - no space, no newline. How many words before `@` are there? – Ted Lyngmo Feb 15 '23 at 19:36
  • @TedLyngmo you'll be happy to know that this is left as an exercise for the reader, and is also outside the scope of this chapter :) – Douglas B Feb 15 '23 at 19:46