Using an array to hold characters for a switch Statement

Hi there,

So i just need a little guidance about if I've gone totally the wrong direction and over-complicated everything, and why my switch statement wont work. Thanks !!

This is the question we were asked to write code for :

To make phone numbers easier to remember, some companies use letters to show their phone
numbers. For example, using letters, the telephone number 438 5626 can be shown as GET
LOAN. In some cases, to make numbers more meaningful, companies may use more than
seven letters. For example, 225 5466 can be displayed as CALL HOME, which uses eight
letters.
Write a C++ program that reads a list of telephone numbers expressed in capital letters from a
text file and converts the telephone numbers in capital letters, to the corresponding telephone
numbers in digits. Each converted phone number should be displayed on the console in both
formats, alphabetic and digital. At the same time, the program creates another file in which the
telephone numbers appear in digital format, one number per line. Allow the user to specify the
name of the input file, as well as the name of the output file.
Apply the following convention: If a number consists of more than seven letters, only the first
seven letters are processed. A space is displayed between the third and fourth digits. Letters A,
B and C corresponds to digit 2; letters D, E and F to digit 3; letters G, H and I to digit 4; letters J,
K and L to digit 5; letters M, N and O to digit 6; letters P, Q R and S to digit 7; letters T, U and V
to digit 8; and letters W, X, Y and Z to digit 9. If any other character is encountered, a * is
displayed.

This is my answer:

#include<iostream>
#include<cstdlib>
#include<fstream>
using namespace std;

int main ()
{
char file_nameIn [16], file_nameOut[16], letter[8], sinLet;
string number;
ifstream in_stream;
ofstream out_stream;
int num;

cout << "Enter the file name for Input (max 15 characters) :" << endl;
cin >> file_nameIn;

cout << "Enter the file name for Output (max 15 characters) :" << endl;
cin >> file_nameOut;

in_stream.open("file_nameIn.dat");
if(in_stream.fail())
{
cout << "Input file opening failed.\n";
exit(1);
}

out_stream.open("file_nameOut.dat");
if(out_stream.fail())
{
cout << "Output file opening failed.\n";
exit(1);
}

while(! in_stream.eof())
{
in_stream >> number;
in_stream >> letter;

cout << number ;

for(num = 0 ; num <= 6 ; num++)
{
if (int num == 3) //error :expected primary expression before int
cout << " ";
else
{
switch (letter(num))//error :letter cant be used as function
{
case 'A' :
case 'B' :
case 'C' :
cout << 2 ;
out_stream << 2;
break;
case 'D' :
case 'E' :
case 'F' :
cout << 3 ;
out_stream << 3;
break;
case 'G' :
case 'H' :
case 'I':
cout << 4 ;
out_stream << 4;
break;
case 'J' :
case 'K' :
case 'L' :
cout << 5 ;
out_stream << 5;
break;
case 'M' :
case 'N' :
case 'O' :
cout << 6 ;
out_stream << 6;
break;
case 'P':
case 'Q':
case 'R':
case 'S':
cout << 7 ;
out_stream << 7;
break;
case 'T':
case 'U' :
case 'V' :
cout << 8 ;
out_stream << 8;
break;
case 'W' :
case 'X' :
case 'Y' :
case 'Z' :
cout << 9 ;
out_stream << 9;
break;
default:
cout << "*";
out_stream << "*";
}
}
}
}

in_stream.close();
out_stream.close();

return 0;
}

Last edited on
Please edit your post to put [code][/code] tags around the code.
First ,include <string>.
Why do you have this
 
if(int num==3)

Remove int.
Why do you use letter(num)?
You must try smth like this
1
2
if(letter[i]=='character')
do ...

Why do you have in_stream >> number;
in_stream >> letter;
You must firs write in your letter variable and the put in outputfile.
Edit:If you do not manage alone post what you have done and I will try to help you.


Last edited on
Try this code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include<iostream>
#include<cstdlib>
#include<fstream>
#include <string>
using namespace std;

int main()
{
	char file_nameIn[16], file_nameOut[16];
	string number,number_help;
	ifstream in_stream;
	ofstream out_stream;
	

	cout << "Enter the file name for Input (max 15 characters) :" << endl;
	cin >> file_nameIn;

	cout << "Enter the file name for Output (max 15 characters) :" << endl;
	cin >> file_nameOut;

	in_stream.open("file_nameIn.dat");
	if (in_stream.fail())
	{
		cout << "Input file opening failed.\n";
		exit(1);
	}
	out_stream.open("file_nameOut.dat");
	if (out_stream.fail())
	{
		cout << "Output file opening failed.\n";
		exit(1);
	}
	while (in_stream >> number)//While all wors do not get read
	{
		cout << number<<endl;
		
		for (int i = 0; i < 7; i++)
		
			if (number[i] > 'a'&&number[i]<'z'&&number[i]>'A'&&number[i] < 'Z')//checking if it is a letter
			
				switch (number[i])//error :letter cant be used as function
				{
				case 'A':(number_help[i] << 2);
				case 'B':(number_help[i] << 2);
				case 'C':(number_help[i] << 2);

					
					break;
				case 'D':(number_help[i] << 3);
				case 'E':(number_help[i] << 3);
				case 'F':(number_help[i] << 3);
					
					break;
				case 'G':(number_help[i] << 4);
				case 'H':(number_help[i] << 4);
				case 'I':(number_help[i] << 4);
					
					break;
				case 'J':(number_help[i] << 5);
				case 'K':(number_help[i] << 5);
				case 'L':(number_help[i] << 5);
					break;
				case 'M':(number_help[i] << 6);
				case 'N':(number_help[i] << 6);
				case 'O':(number_help[i] << 6);
					
					break;
				case 'P':(number_help[i] << 7);
				case 'Q':(number_help[i] << 7);
				case 'R':(number_help[i] << 7);
				case 'S':(number_help[i] << 7);
					
					break;
				case 'T':(number_help[i] << 8);
				case 'U':(number_help[i] << 8);
				case 'V':(number_help[i] << 8);
					
					break;
				case 'W':(number_help[i] << 9);
				case 'X':(number_help[i] << 9);
				case 'Y':(number_help[i] << 9);
				case 'Z':(number_help[i] << 9);
					
					break;
				}
			else
		(number_help[i] << '*');//if it is not a letter we put *
	
		number_help.insert(3, 1, ' ');//Inserting space on the 3rd position
		cout << number_help << endl;
	out_stream <<number_help<< endl;//When all is ended

			}
			
	in_stream.close();
	out_stream.close();






			return 0;
		}
	
Use std::map<char,int>
char file_nameIn[16], file_nameOut[16], letter[8], sinLet;
Don't use fixed-length character arrays unless you really mean to limit the length of the string AND you enforce that limitation in the code. So change these to strings:
string file_nameIn, file_nameOut, letters;
Notice that I changed letter to letters to make it clear that this contains more than one letter. Clear names really matter.

1
2
3
in_stream.open("file_nameIn.dat");
...
out_stream.open("file_nameOut.dat");

These will open files that are literally named "file_nameIn.dat" and "file_nameOut.dat". You want to use the names contained in the variables with those names, so it should be:
1
2
3
in_stream.open(file_nameIn);
...
out_stream.open(file_nameOut);


To switch on a character within a string, use [] instead of (), so you want switch(letters[num]).

1
2
3
if (int num == 3)
   number += " ";
else {

You still need to convert the 3rd letter of the input, so no need for the else.

Right now your code converts the letters to digits and outputs the result at the same time. That sort of works, but you have to output to cout and also out_stream each time. And what if the prof changes the assignment slightly to ask you to output with, say, a business name? It would be much more robust to convert the letters into a string of digits first. Then you can output the letters and digits where ever you like. This is an example of a general principle: separate your computations from your I/O

Putting it all together, this gets your code pretty close:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include<iostream>
#include<cstdlib>
#include<fstream>
using namespace std;

int
main()
{
    string file_nameIn, file_nameOut, letters;
    string number;
    ifstream in_stream;
    ofstream out_stream;
    int num;

    cout << "Enter the file name for Input (max 15 characters) :" << endl;
    cin >> file_nameIn;

    cout << "Enter the file name for Output (max 15 characters) :" << endl;
    cin >> file_nameOut;

    in_stream.open(file_nameIn);
    if (in_stream.fail()) {
	cout << "Input file opening failed.\n";
	exit(1);
    }

    out_stream.open(file_nameOut);
    if (out_stream.fail()) {
	cout << "Output file opening failed.\n";
	exit(1);
    }

    while (!in_stream.eof()) {
	in_stream >> letters;

	// convert letters to number
	number.clear();
	for (num = 0; num <= 6; num++) {
	    if (num == 3)			 //error :expected primary expression before int
		number += " ";
	    switch (letters[num])		 //error :letter cant be used as function
		{
		case 'A':
		case 'B':
		case 'C':
		    number += '2';
		    break;
		case 'D':
		case 'E':
		case 'F':
		    number += '3';
		    break;
		case 'G':
		case 'H':
		case 'I':
		    number += '4';
		    break;
		case 'J':
		case 'K':
		case 'L':
		    number += '5';
		    break;
		case 'M':
		case 'N':
		case 'O':
		    number += '6';
		    break;
		case 'P':
		case 'Q':
		case 'R':
		case 'S':
		    number += '7';
		    break;
		case 'T':
		case 'U':
		case 'V':
		    number += '8';
		    break;
		case 'W':
		case 'X':
		case 'Y':
		case 'Z':
		    number += '9';
		    break;
		default:
		    number += '*';
		}
	}

	// Now write the output
	cout << letters << '\t' << number << '\n';
	out_stream << number << '\n';
    }

    in_stream.close();
    out_stream.close();

    return 0;
}


lastchance writes:
Use std::map<char,int>

Actually, a simple C string will do. Here's a string that contains the digit that corresponds
to each letter. The comment helps show which digit corresponds to which letter.
1
2
    //                      ABCDEFGHIJKLMNOPQRSTUVWXYZ
    static char theMap[] = "22233344455566677778889999";

Now, given a letter like char ch = letters[num], you can almost get the digit with theMap[ch]. I say "almost" because when ch is 'A', this will try to access theMap[65] instead of theMap[0] because the program converts 'A' to an integer using it's ASCII value, which is 65.

But it's trivial to fix that, just subtract 65 from the index! theMap[ch-65] will give the digit character that corresponds to the letter. To make it clearer what you're doing, it's better to let the compiler determine the ASCII value to subtract: theMap[ch-'A']. This says "take the ASCII value if the character, subtract the ASCII value of letter 'A' and use that number as the index into the array. So if ch is 'A', it will look up theMap[0]. If ch is 'B' it will look up theMap[1], etc.

Now, you just have to make sure you're passing in an upper case character. You can do that with an if statement. I'll add the step to append the character to the "number" string:
1
2
3
4
5
6
7
char outputCh;
if (isUpper(ch)) {
    outputCh = theMap[ch-'A'];
} else {
    outputCh = '*';
}
number += outputCh;


And that replaces your entire 46 line switch statement.

@zwojn
Line 39: Your if statement is flawed. It will never be true. A letter can't be both lower case and upper case at the same time.

Line 41: Your switch statement works only for upper case letters. You never upshift lower chase letters. Not sure what you meant by your error comment.

Line 42-82: What do you think the << operator does here? You don't want to insert a binary number into a string. Perhaps you meant:
 
case 'A': number_help[i] = '2'; 






&AbstactionAnon
Line 39 :Yes my mistake.I should have putted || in the place of second AND.
 
if(number[i] > 'a'&&number[i]<'z' || number[i]>'A'&&number[i] < 'Z')

I think upper letters should be used in the task.
Line 42-82-You have a point.I have made a mistake there.
Regarding lower case letters, this is a good example of where it pays to read the assignment very carefully. It says:
Write a C++ program that reads a list of telephone numbers expressed in capital letters
and later:
Letters A, B and C corresponds to digit 2; letters D, E and F to digit 3 [...] If any other character is encountered, a * is displayed.

So lower case letters should be treated as any other non-uppercase character and should result in a '*'.
Topic archived. No new replies allowed.