Reputation:
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
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
Reputation: 42828
You shouldn't. switch
statements work based on ==
, not <=
/ >=
/ <
/ >
.
The case
s 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
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
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