user4323636
user4323636

Reputation:

How do I do this with switch instead of if esle?

I am taking my first programming course and the assignment was to redo a previous program (this one) using a switch statement. I thought that switch was just used to compare single characters.

The program essentially just receives a string and counts numbers, letters, other characters, and total characters.....

#include <iostream> 
using namespace std;

int main()
{
    char s[50];
    int i;
    int total = 0;
    int letters = 0;
    int numbers = 0;
    int others = 0;    

    cout << "Enter a continuous string of characters with no blank spaces" << endl;
    cout << "(example: aBc1234!@#$%)" << endl << endl;
    cout << "Enter your string: ";
    cin >> s;
    cout << endl;

    i = 0;
    while (s[i] != 0)
    {
        if ((s[i] >= 'A' && s[i] <= 'Z') || (s[i] >= 'a' && s[i] <= 'z'))
            letters++;
        else if ((s[i] >= '0' && s[i] <= '9'))
            numbers++;
        else
            others++;
        i++;
        total++;
    }

    cout << letters << " letters" << endl;
    cout << numbers << " numbers" << endl;
    cout << others << " other characters" << endl;


    return 0;
}

Upvotes: 0

Views: 122

Answers (4)

Ben Voigt
Ben Voigt

Reputation: 283614

You need a mapping from all the characters of interest onto the behaviors.

enum char_category { OTHER, LETTER, NUMBER };
unsigned char mapping[256];

memset(mapping, OTHER, sizeof mapping);

for( char ch = '0'; ch <= '9'; ++ch ) mapping[ch] = NUMBER;
for( char ch = 'A'; ch <= 'Z'; ++ch ) mapping[ch] = mapping[tolower(ch)] = LETTER;

Then you can use a jump table:

switch ( mapping[s[i]] )
{
    case NUMBER:
        break;
    case LETTER:
        break;
    case OTHER:
        break;
}

Or you could completely skip the conditionals:

int count[3] = { 0, 0, 0 };

count[mapping[s[i]]]++;

letters = count[LETTER];
numbers = count[NUMBER];
other = count[OTHER];

Note that the work of setting up the mapping is only justified if you have more than a few dozen input characters.

Upvotes: 1

Emil Laine
Emil Laine

Reputation: 42828

You shouldn't. switch statements work based on ==, not <= / >= / < / >.

The cases in a switch statement must be constant expressions. You'd have to make a separate case for each character.

There are situations where switch is a better solution. But this is not one of those situations. Here if and else is the way to go.

Upvotes: 2

Kvothe
Kvothe

Reputation: 1837

With this particular situation if/else is the best way (as said by @zenith) but if you wished do to it with switch statements you would do

switch(s[i])
{
    case `0`:
    case '1':
    case '2':
    //repeat for '3'-'8'
    case '9':
        //do whatever you want when it is a digit here
        break;
    case 'A':
    case 'a':
    case 'B':
    case 'b':
    //repeat for 'C'-'y'
    case 'Z':
    case 'z':
        //do whatever you want when it is a letter
        break;
    default:
        //do whatever you want when it was not a letter or a digit
        break;
}

When a case matches in a switch statement, everything up to the corresponding break is executed - that's how you can group cases like this

Upvotes: 3

zorbathegeek
zorbathegeek

Reputation: 88

switch(s[i]) {
    case '0':
    ...
    case '9': numbers++; break;
    default: {
        switch(toupper(s[i])) {
            case 'A':
            case 'B':
            ...
            case 'Z': letters++; break;
            default: others++;
        }
     }
}    

Upvotes: 0

Related Questions