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:
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.