Example:

There are literally hundreds of programming languages.

The number of nonblank characters is : 48

So far i have come up with:

for (cin.get(inputLetter); inputLetter != '\n'; cin.get(inputLetter))
{
if ((inputLetter >= 'A' || 'a') && (inputLetter <= 'Z' || 'z'))
numUpper++;


}

Recommended Answers

All 6 Replies

well, you may try using FOR Loops!!

den Counter++;

>>if ((inputLetter >= 'A' || 'a') && (inputLetter <= 'Z' || 'z'))

You can't use the || operator like that. Here is how you have to do that if ((inputLetter >= 'A' && inputLetter <= 'Z') || (inputLetter >='a' && inputLetter <='z')) A better way is to convert the letter to upper case (or lower case) then do just one comparison

inputLetter = toupper(inputLetter);
if( toupper(inputLetter) )
{
   // blabla
}

Edward is confused. The topic asks a different question than the example output suggests, and the example code doesn't solve the same problem as the example output suggests. :confused: Are you counting all characters, all non-blank characters, all upper case characters, or something else entirely?

Anyway, since the problem seems to be one of character classification, it's better to solve it directly using the standard library instead of doing it manually or indirectly:

#include <cctype>
#include <iostream>

int main()
{
  using namespace std;

  int upper = 0;
  int lower = 0;
  int alpha = 0;
  char ch;

  while (cin.get(ch)) {
    if (isalpha(ch)) {
      ++alpha;

      if (isupper(ch))
        ++upper;
      else if (islower(ch))
        ++lower;
    }
  }

  cout << "Alpha: " << alpha << '\n'
    << "Upper: " << upper << '\n'
    << "Lower: " << lower << '\n';
}

This can be extended for just about any basic test you might need using the standard C character class functions.

The character class functions are better because they'll still work for other languages where the classification rules might be different, but the manual test only works for english and languages with the same casing rules.

// Always true!
if( toupper(inputLetter) )
{
   // blabla
}

toupper() returns the converted character or the unconverted character if there's no upper case equivalent. Unless inputLetter has a value of 0, that if statement will always be true. Ed's guess is that this is a typo and you meant isupper() instead of toupper(). :)

Never forget to test end of stream condition (avoid loop forever):

const int eof = char_traits<int>::eof();
    int ch, n;
    for (;;)
    {
        cout << ">"; cout.flush();
        for (n = 0; (ch=cin.get()) != eof && ch != '\n'; ++n)
        {
            // process ch as you wish
        }
        if (!cin)
            break;
        cout << n << " chars" << endl;
    }
// Not needed if the right overload of cin.get() is used
const int eof = char_traits<int>::eof();
int ch, n;

// Infinite loops feel kudgy; maybe a do loop instead?
for (;;)
{
    // flush() isn't needed here
    cout << ">"; cout.flush();

    // istream& get(char&) wouldn't be as verbose
    for (n = 0; (ch=cin.get()) != eof && ch != '\n'; ++n)
    {
        // process ch as you wish
    }
    if (!cin)
        break;
    cout << n << " chars" << endl;
}

The first flush isn't needed because the next operation is to read a character with cin.get(). cin is tied to cout, and that means every extraction from cin will automatically flush cout first.

That whole char_traits<> thing is a lot of work and extra code just to test for eof. Why not use the overload of cin.get() that returns the stream object and let the void* conversion do the work for you? :)

do {
  cout << ">";

  char ch;
  int n;

  for (n = 0; cin.get(ch) && ch != '\n'; ++n) {
    // process ch as you wish
  }

  if (!cin.eof())
    cout << n << " chars" << endl;
} while (cin.good());

It's a good practice to limit the scope of variables as much as possible, so Ed moved ch and n inside the loop. Also, a do loop flows better than an infinite loop for this solution, I think. :)

cin.get(ch) is better than (ch=cin.get()), I agree.

About for and do loops: I think, it's one of well-known loop patterns:

loop
   prepare the step...
        if nothing to do then break
   do the real work
end loop

In this case:

loop
     try to count user input
          if nothing to do (eof occured) then break
     print counter
loop again

That's just what a reader expects after for (;;) line.
do-while loop corresponds to another pattern:

loop
     do the step unconditionally    
loop until all done

So I don't like two absolutely identical condition checks in do-while variant presented above.

Of course, tastes differ.

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.