The output comes out wrong it should be different:

//This is what I have

Enter a sentence: Today Is Thr Jan, 2015
  Number of uppercase letters.........2
  Number of digits....................2
  Number of vowels....................2
Press any key to continue . . .

//The output should look like this:

Enter a sentence: Today Is Thr Jan, 2015
  Number of uppercase letters.........4
  Number of digits....................4
  Number of vowels....................4
Press any key to continue . . .




#include <iostream> 
#include <iomanip> 
#include <string>

using namespace std;

int main()
{
    char c;
    int Uc = 0, Dc=0, Vc=0;
    string vowels("aeiouAEIOU");

    cout << "Enter a sentence: ";
    cin.get(c);
    while(c != '\n')
    {
        {
        if(isupper(c))  
            Uc++;  
        if(isdigit(c)) 
            Dc++; 
        cin.get(c);
        }
        {
        if(vowels.find(c) != string::npos)
            Vc++;
        cin.get(c);
        }
    }
     cout << setfill ('.');
     cout << "  Number of uppercase letters" << right << setw(10) << Uc << endl; 
     cout << "  Number of digits" << right << setw(22) << Dc << endl; 
     cout << "  Number of vowels" << right << setw(22) << Vc << endl;

     system("pause");
    return 0;
}

Dani AI

Generated

correctly identified the root cause: the input is being advanced twice per loop, so every second character is skipped and the counts end up roughly halved. 's change in post #5 (removing the extra cin.get) addresses the immediate bug.

A few additional, practical suggestions that make the code clearer and more robust:

  • Read the whole line with std::getline and then iterate the characters. That removes manual newline handling and avoids accidentally consuming characters twice.
  • Include <cctype> and call the classification functions with an unsigned char cast (for example std::isupper(static_cast<unsigned char>(ch))) to avoid undefined behaviour on platforms where char is signed.
  • The simple vowels.find(ch) approach is fine for short checks; for case-insensitive matching include both cases in the vowel string or compare after std::tolower.

A compact, safe pattern (reads a full line, counts properly, and avoids repeated input reads):

#include <iostream>
#include <string>
#include <cctype>

int main() {
    std::cout << "Enter a sentence: ";
    std::string line;
    if (!std::getline(std::cin, line)) return 0;

    int uppercase = 0, digits = 0, vowels = 0;
    const std::string VOWELS = "aeiouAEIOU";

    for (char ch : line) {
        unsigned char uch = static_cast<unsigned char>(ch);
        if (std::isupper(uch)) ++uppercase;
        if (std::isdigit(uch)) ++digits;
        if (VOWELS.find(ch) != std::string::npos) ++vowels;
    }

    std::cout << "  Number of uppercase letters........." << uppercase << '\n';
    std::cout << "  Number of digits...................." << digits << '\n';
    std::cout << "  Number of vowels...................." << vowels << '\n';
    return 0;
}

Notes: avoid system("pause") for portability (use a final std::cin.get() if a pause is needed), and adjust setfill/setw if alignment of the dots matters. For very long inputs, a small lookup table is faster than repeated find, but for single-line sentences this is unnecessary.

Recommended Answers

All 5 Replies

Each time round the loop you have 2 cin.get(c); lines. I suspect that you only want the one at the end of the loop.

Not sure what exactly you mean?

I'm supposed to get 4, 4, 4 for uppercase, digits, and vowels but its giving me 2, 2, 2 right now

Oh, so you mean like this: ?

    while(c != '\n')
    {
        {
        if(isupper(c))  
            Uc++;  
        if(isdigit(c)) 
            Dc++; 
        if(vowels.find(c) != string::npos)
            Vc++;
        cin.get(c);
        }
    }

Yes, exactly. Does that solve your problem?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.