c++ array phonetic alphabet program
My last program before finals week involves inputting a string and then outputting it in phonetic form. I have to use an array to get the values, so i figured a pre dtermined value array would work like such:
string phonetic[25] = {Alpha, Bravo, Charlie, … , Zulu};
but it seems I am still a little confused on another thing. I can get each char by using nameofstring.at(x) and then increment that to keep going in a loop, but how do I decide a value for letters? I got very confused from my online book on this matter, and it seems like it isnt just 1-26 for the alphabet, but like goes to 9 then something wierd. Can someone tell me how to get a value?
Also, I belive to get values lowered from uppercase to lower I can subtract A, but if this is wrong, please tell me now so i can say something to the professor because this quarter has been the worst programming I have don in 6 years, as far as doing a chapter a week and not getting my full potential from it.
Sorry for any stupidity in my writing, as it is 4am. ;)
thanks in advance
A char is represented as it's ASCII value: an integer. Look at http://asciitable.com/ and see why subtracting 'A' makes sense.
vegeta_man111 wrote: string phonetic[25] = {Alpha, Bravo, Charlie, … , Zulu}; There are 26 letters in the alphabet. Also, you need speech marks around each word to make it a string:
markupstring phonetic[26] = {"Alpha", "Bravo", "Charlie", ... , "Zulu"};
You could just let the compiler work out how big the array is as well:markupstring phonetic[] = {"Alpha", "Bravo", "Charlie", ... , "Zulu"};
vegeta_man111 wrote: but it seems I am still a little confused on another thing. I can get each char by using nameofstring.at(x) and then increment that to keep going in a loop, but how do I decide a value for letters? What is letters? Post your code or more some detailed information please.
starofale wrote: Also, you need speech marks around each word to make it a string:
markupstring phonetic[26] = {"Alpha", "Bravo", "Charlie", ... , "Zulu"};
Actually, with the quotes you make a null-terminated character array. Luckily the string class has a constructor with a char pointer as its argument.
OP, this is what you want, right?
string word = "blah";
for(int i = 0; i < word.length(); ++i)
cout << phonetic[blah.at(i)-96] << endl;```
This goes horribly wrong when *word* contains non-[a-z] characters though.
EDIT:
Xunxen: I know, that's why I said a-z and not a-zA-Z...
Com: Of course it's a class encasing of a C-style string, but that's the whole point. I was just explaining that putting quotes around something doesn't automatically make it a string object. And thanks for pointing out my typo, word.at indeed ;-)
@GTA, that also goes horribly wrong if the letters are upper case, as the values range from 65-90. it's best to check that it's between 'A' and 'Z' and if it is, subtract 'A' and check if it's between 'a' and 'z' and subtract 'a', otherwise, maybe throw an exception? you're trying to get the phonetic letters, so you don't really need numbers, just make sure they're not there.
GTADarkDude wrote: [quote]starofale wrote: Also, you need speech marks around each word to make it a string:
markupstring phonetic[26] = {"Alpha", "Bravo", "Charlie", ... , "Zulu"};
Actually, with the quotes you make a null-terminated character array. Luckily the string class has a constructor with a char pointer as its argument.
OP, this is what you want, right?
string word = "blah";
for(int i = 0; i < word.length(); ++i)
cout << phonetic[blah.at(i)-96] << endl;```
This goes horribly wrong when *word* contains non-[a-z] characters though.[/quote]
Of course it makes a null terminated string, the C++ string is just a class encasing C-style strings with more functionality last I checked. The other way he'd be sending variables, you can't even tell if they exist or not.
Also, I assume that you mean word.at and not blah.at.
> **Xunxen wrote:**
@GTA, that also goes horribly wrong if the letters are upper case, as the values range from 65-90.
it's best to check that it's between 'A' and 'Z' and if it is, subtract 'A' and check if it's between 'a' and 'z' and subtract 'a', otherwise, maybe throw an exception? you're trying to get the phonetic letters, so you don't really need numbers, just make sure they're not there.
It is also not properly portable in the case that the ranges would be different. Personally, I'd do a switch case for this with a fallthrough for upper and lower case letters.
Personally, I'd do a switch case for this with a fallthrough for upper and lower case letters.
indeed
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
string word, phonetic[] = { "Alpha", "Bravo", "Charlie", "Delta", "Echo",
"Foxtrot", "Golf", "Hotel", "India", "Juliet",
"Kilo", "Lima", "Mike", "November", "Oscar",
"Papa", "Quebec", "Romeo", "Sierra", "Tango",
"Uniform", "Victor", "Whiskey", "X-ray",
"Yankee", "Zulu" };
if(argc == 2) {
word = argv[1];
} else return(-1);
for(int x = 0; x < word.length(); x++)
{
switch(word.at(x))
{
case 'a':
case 'A': cout << phonetic[0] << endl; break;
case 'b':
case 'B': cout << phonetic[1] << endl; break;
//etc
default: cout << "Invalid character" << endl; break;
}
}
return(0);
}
[me@local ~]# g++ -o h h.cpp
[me@local ~]# ./h aAbBz
Alpha
Alpha
Bravo
Bravo
Invalid character
if the code is suppose to work in a similar manner as iBlaze's code then i should also use a tolower/toupper function to get all the letter in to lower or upper case and then write the switch case on that letter.
i believe that there is such a function in the ctype.h header file and if there is not then you could alway write your own that could look something like this:
char toUpper(char letter)
{
if(letter >= 'a' && letter <= 'z')
return (letter - ('a' - 'A'));
return (letter)
}
this way if the is in lower case it gets in to upper and if it is in anything but lower case it just returns it's current value.
and if you had problems with understanding why you subtract 'A' from the letter that you currenently have is because you are going to end up in the right array index.
for exampel char hello[] = {'A', 'B', 'C'…….'Z'}; // hello[0] == 'A' hello[1] == 'B' … hello[26] == 'Z' // your letter is for exampel D, d in ascii is 67(A)+4 = 71 // so when you write hello[letter - 'A'] what you really is writing is // hello[71 - 67] == hello[3] which is the index position for the D letter
hope this clarifies something instead of just making it worse.
// shazrah;)
vegeta_man111 wrote: sorry, i forgot that part. This program is a revision of a switch based program and we are not allowed to use switches. Oh christ… why would they do that? Why would they try to teach you something that will probably end up being effectively worse? The switch statement is specifically designed to be fast; I see absolutely no reason for not using it here. But sigh, fine. If they insist then you may as well use the isalpha() function to check, make it lower or uppercase as per your preference and then search for that in a string of the abc, using the returned value as the index for your string array. Yes, this is really fucking convoluted in comparison and pointless when you could use a switch instead, but whatever.
COM wrote: [quote]vegeta_man111 wrote: sorry, i forgot that part. This program is a revision of a switch based program and we are not allowed to use switches. Oh christ… why would they do that? Why would they try to teach you something that will probably end up being effectively worse? The switch statement is specifically designed to be fast; I see absolutely no reason for not using it here. But sigh, fine. If they insist then you may as well use the isalpha() function to check, make it lower or uppercase as per your preference and then search for that in a string of the abc, using the returned value as the index for your string array. Yes, this is really fucking convoluted in comparison and pointless when you could use a switch instead, but whatever.[/quote]
I agree and cant wait to do the quarterly survey.
this is what I have so far, but it has a runtime error.
// Chapter X Assignment X
// Corey Hartshorn
#include <iostream>
#include <string>
#include <ctype.h>
using namespace std;
int main ()
{
string phonetic[] = { "Alpha", "Bravo", "Charlie", "Delta", "Echo",
"Foxtrot", "Golf", "Hotel", "India", "Juliet",
"Kilo", "Lima", "Mike", "November", "Oscar",
"Papa", "Quebec", "Romeo", "Sierra", "Tango",
"Uniform", "Victor", "Whiskey", "X-ray",
"Yankee", "Zulu" };
string word;
char letter;
cout <<"Input a word or sentence:" << endl;
cin >> word;
for(int x = 0; x <= word.length(); x++)
{
letter = word.at(x);
if (isalpha(letter))
{
putchar (toupper(letter));
cout << phonetic[letter - 65] << " - ";
}
else
{
cout << letter << " is not a letter" << endl;
x = word.length() + 1;
}
}
system("pause");
return 0;
}
//******************************************************************************
- Loop < word.length(), not <=. A length of 5 means that indexes 0 up to and including 4 are usable.
- Just so to let you know, letter doesn't change by calling toupper. So in phonetic[letter - 65], you're still using the lowercase letter (unless the letter was uppercase anyways of course).
- Well this is just some strong advice: don't mix C and C++ I/O functions, it's messy.
- Some other advice: x = word.length() + 1 is ugly. Just use break;, or, if you want to avoid that too, rewrite your code in such a way that you can use isalpha(letter) in the loop condition.
- Even more advice: don't use system() calls. For one thing it's pretty slow, but even worse is that is makes your program platform dependent. "pause" is a Windows-only command.
thanks for the advice. I have been trying to find a good way around using system() but I dont have a linux based computer yet so I cant test anything out. ANy suggestions?
updated code:
// Chapter X Assignment X
// Corey Hartshorn
#include <iostream>
#include <string>
#include <ctype.h>
using namespace std;
int main ()
{
string phonetic[] = { "Alpha", "Bravo", "Charlie", "Delta", "Echo",
"Foxtrot", "Golf", "Hotel", "India", "Juliet",
"Kilo", "Lima", "Mike", "November", "Oscar",
"Papa", "Quebec", "Romeo", "Sierra", "Tango",
"Uniform", "Victor", "Whiskey", "X-ray",
"Yankee", "Zulu" };
string word;
char letter;
cout <<"Input a word or sentence:" << endl;
cin >> word;
for(int x = 0; x < word.length(); x++)
{
letter = word.at(x);
if (isalpha(letter))
{
cout << phonetic[putchar (toupper(letter)) - 65] << " - ";
}
else
{
cout << letter << " is not a letter" << endl;
break;
}
}
system("pause");
return 0;
}
//******************************************************************************
To "pause", like DOS does, just waiting for keyboard input:
C
printf("Press any key to [something]...\n");
while(!(getch() > 0)) {}
C++
cout << "Press any key to [something]..." << endl;
while(!(cin.get() > 0)) {}
I am not sure if this is really the most optimal solution but at least reduces the dependancy on Shell fuctions/DOS functions.
Hope that helps…
Jim,
j4m32 wrote: To "pause", like DOS does, just waiting for keyboard input:
C
printf("Press any key to [something]...\n");
while(!(getch() > 0)) {}
C++
cout << "Press any key to [something]..." << endl;
while(!(cin.get() > 0)) {}
I am not sure if this is really the most optimal solution but at least reduces the dependancy on Shell fuctions/DOS functions.
Hope that helps…
Jim,
seems like this wont work for me.
Xunxen wrote: why not just use getline(null,cin)? then you would have to press return to continue.
it isnt working either.
I did find this from something Jim posted earlier in another of my threads I seemed to have missed (Thanks Jim!)
cin.ignore(1,'\x10');
while(!(cin.get() > 0)) {}```
Now I just need to figure out how to get it to skip over spaces and continue as well as stop saying AAlpha and BBravo and so on.
updated! fixed the letter problem. Putchar makes it print the char so i was literally printing the uppercase letter then printing the phonetic right after it.
// Chapter X Assignment X
// Corey Hartshorn
#include <iostream>
#include <string>
#include <ctype.h>
using namespace std;
int main ()
{
string phonetic[] = { "Alpha", "Bravo", "Charlie", "Delta", "Echo",
"Foxtrot", "Golf", "Hotel", "India", "Juliet",
"Kilo", "Lima", "Mike", "November", "Oscar",
"Papa", "Quebec", "Romeo", "Sierra", "Tango",
"Uniform", "Victor", "Whiskey", "X-ray",
"Yankee", "Zulu" };
string word;
char letter;
cout <<"Input a word or sentence to be output in phonetic form:" << endl;
cin >> word;
for(int x = 0; x < word.length(); x++)
{
letter = word.at(x); // gets each letter by itself
if (isalpha(letter)) // checks to make sure an alphabetical symbol
{
cout << phonetic[(toupper(letter)) - 65] << endl;
} // outputs phonetic alphabet based on alphabetical value
else if (letter == " ");
{
cout << "*SPACE*" << endl;
word = word.substr(x, word.length());
x = 0;
}
else
{
cout << letter << " is not a letter" << endl;
break; // declares not a variable and ends the 'for' loop
}
}
cout << "Press the ENTER key to continue..." << endl;
cin.ignore(1,'\x10');
while(!(cin.get() > 0)) {} // pauses at the end
return 0;
}
started coding a little bit of the else if statement to determine if letter is a space so i can skip over it, but realized i cant compare pointers to integers, which im assuming is meaning i cant compare " " (space) to a character.
letter is a character while " " is a character array, so indeed, you can't compare them like this. You need single quotes if you want to compare to the space character: ' '. Furthermore, word will never contain any spaces. The >> operator reads until the first whitespace it encounters. (Space, newline, tab..) So when you enter "Hey there!", word contains "Hey", and " there!" remains in the input buffer. This is also why you need to call ignore() first, before calling get(). Use getline() if you want to enter a full sentence.
try using ' ' instead of " ". double quotes usually mean a string, while single quotes are a char. you could also do this:
continue;
}```
assuming you convert everything to uppercase before hand, this will skip that iteration of the loop if the character is not a capital letter.
just make sure you use getline() if you want spaces.
it seems that when I use getline() that my pause now needs you to enter twice to exit at the end, but nonetheless it works. Updated code:
// Chapter X Assignment X
// Corey Hartshorn
#include <iostream>
#include <string>
#include <ctype.h>
using namespace std;
int main ()
{
string phonetic[] = { "Alpha", "Bravo", "Charlie", "Delta", "Echo",
"Foxtrot", "Golf", "Hotel", "India", "Juliet",
"Kilo", "Lima", "Mike", "November", "Oscar",
"Papa", "Quebec", "Romeo", "Sierra", "Tango",
"Uniform", "Victor", "Whiskey", "X-ray",
"Yankee", "Zulu" };
string word;
char letter;
cout <<"Input a word or sentence to be output in phonetic form:" << endl;
getline(cin, word);
for(int x = 0; x < word.length(); x++)
{
letter = word.at(x); // gets each letter by itself
if (isalpha(letter)) // checks to make sure an alphabetical symbol
{
cout << phonetic[(toupper(letter)) - 65] << endl;
} // outputs phonetic alphabet based on alphabetical value
else if (letter == ' ')
{
cout << "*SPACE*" << endl; // places a space wherever one is
word = word.substr(x, word.length());
x = 0;
}
else
{
cout << letter << " is not a letter" << endl;
break; // declares not a variable and ends the 'for' loop
}
}
cout << "Press the ENTER key to continue..." << endl;
cin.ignore(1,'\x10');
while(!(cin.get() > 0)) {} // pauses at the end
return 0;
}```
this whole project seems like it'd be easier with an STL map, then you could just dump the the current character in the string into the map as a key and get the phonetic character back.
markupcout << phonetic[toupper(word.at(x))] << endl;
seems much neater than
cout << phonetic[(toupper(letter)) - 65] << endl;```
(I feel like that last line needs an explicit type cast, but that could just be me.)
although a map would probably defeat the purpose of the project in the first place.
also, you could use mod 26 to get the integer value of the letter (after converting to upper),but 'A' would be 13, so your phonetic array would have to start with "Alpha" in the 13th index, then "November" would be in the 0th index. it could be fun just to see how much you could confuse your teacher with that...