Welcome to HBH! If you had an account on hellboundhacker.org you will need to reset your password using the Lost Password system before you will be able to login.

c++ array phonetic alphabet program


ghost's Avatar
0 0

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


starofale's Avatar
Member
0 0

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.


GTADarkDude's Avatar
Member
0 0

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 ;-)

Xunxen's Avatar
Member
0 0

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


ghost's Avatar
0 0

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.

ghost's Avatar
0 0

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


ghost's Avatar
0 0

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;)


ghost's Avatar
0 0

I understand everything being said so far. Thanks for your help everyone. Now, onto the letter issue. My professor says to use isalpha() to check if a letter is actually a letter. Is this correct?


ghost's Avatar
0 0

vegeta_man111 wrote: Now, onto the letter issue. My professor says to use isalpha() to check if a letter is actually a letter. Is this correct? What letter issue? Why would you need to use that function for a switch case approach?


ghost's Avatar
0 0

sorry, i forgot that part. This program is a revision of a switch based program and we are not allowed to use switches.


ghost's Avatar
0 0

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.


ghost's Avatar
0 0

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.


ghost's Avatar
0 0

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;
}
//******************************************************************************



GTADarkDude's Avatar
Member
0 0
  1. Loop < word.length(), not <=. A length of 5 means that indexes 0 up to and including 4 are usable.
  2. 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).
  3. Well this is just some strong advice: don't mix C and C++ I/O functions, it's messy.
  4. 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.
  5. 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.

ghost's Avatar
0 0

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 &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;ctype.h&gt;
using namespace std;

int main ()
{
    string phonetic[] = { &quot;Alpha&quot;, &quot;Bravo&quot;, &quot;Charlie&quot;, &quot;Delta&quot;, &quot;Echo&quot;,
                                &quot;Foxtrot&quot;, &quot;Golf&quot;, &quot;Hotel&quot;, &quot;India&quot;, &quot;Juliet&quot;,
                                &quot;Kilo&quot;, &quot;Lima&quot;, &quot;Mike&quot;, &quot;November&quot;, &quot;Oscar&quot;,
                                &quot;Papa&quot;, &quot;Quebec&quot;, &quot;Romeo&quot;, &quot;Sierra&quot;, &quot;Tango&quot;,
                                &quot;Uniform&quot;, &quot;Victor&quot;, &quot;Whiskey&quot;, &quot;X-ray&quot;,
                                &quot;Yankee&quot;, &quot;Zulu&quot; };
    string word;
    char letter;
    
    
    
    cout &lt;&lt;&quot;Input a word or sentence:&quot; &lt;&lt; endl;
    cin &gt;&gt; word;

    
    for(int x = 0; x &lt; word.length(); x++)
    {
        letter = word.at(x);
        if (isalpha(letter))
        {
             
             cout &lt;&lt; phonetic[putchar (toupper(letter)) - 65] &lt;&lt; &quot; - &quot;;
        }
        else 
        {
        cout &lt;&lt; letter &lt;&lt; &quot; is not a letter&quot; &lt;&lt; endl;
        break;
        }
    }
    system(&quot;pause&quot;);
    return 0;
}
//******************************************************************************



ghost's Avatar
0 0

also, the other problems I am running into are that: a.) when i input abcd i get output of "AAlpha - BBravo - … etc." b.) when I have a space it stops at it and ends, how do you think I can set it up to out something like SPACE and then keep going?


j4m32's Avatar
Member
0 0

To "pause", like DOS does, just waiting for keyboard input:

C

printf(&quot;Press any key to [something]...&#92;n&quot;);
while(!(getch() &gt; 0)) {}

C++

cout &lt;&lt; &quot;Press any key to [something]...&quot; &lt;&lt; endl;
while(!(cin.get() &gt; 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,


ghost's Avatar
0 0

j4m32 wrote: To "pause", like DOS does, just waiting for keyboard input:

C

printf(&quot;Press any key to [something]...&#92;n&quot;);
while(!(getch() &gt; 0)) {}

C++

cout &lt;&lt; &quot;Press any key to [something]...&quot; &lt;&lt; endl;
while(!(cin.get() &gt; 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's Avatar
Member
0 0

why not just use getline(null,cin)? then you would have to press return to continue.


ghost's Avatar
0 0

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,&#39;&#92;x10&#39;);
while(!(cin.get() &gt; 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.

ghost's Avatar
0 0

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 &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;ctype.h&gt;
using namespace std;

int main ()
{
    string phonetic[] = { &quot;Alpha&quot;, &quot;Bravo&quot;, &quot;Charlie&quot;, &quot;Delta&quot;, &quot;Echo&quot;,
                                &quot;Foxtrot&quot;, &quot;Golf&quot;, &quot;Hotel&quot;, &quot;India&quot;, &quot;Juliet&quot;,
                                &quot;Kilo&quot;, &quot;Lima&quot;, &quot;Mike&quot;, &quot;November&quot;, &quot;Oscar&quot;,
                                &quot;Papa&quot;, &quot;Quebec&quot;, &quot;Romeo&quot;, &quot;Sierra&quot;, &quot;Tango&quot;,
                                &quot;Uniform&quot;, &quot;Victor&quot;, &quot;Whiskey&quot;, &quot;X-ray&quot;,
                                &quot;Yankee&quot;, &quot;Zulu&quot; };
    string word;
    char letter;
    
    
    
    cout &lt;&lt;&quot;Input a word or sentence to be output in phonetic form:&quot; &lt;&lt; endl; 
    cin &gt;&gt; word;

    
    for(int x = 0; x &lt; word.length(); x++)
    {
        letter = word.at(x); // gets each letter by itself
        if (isalpha(letter)) // checks to make sure an alphabetical symbol
        {
             
             cout &lt;&lt; phonetic[(toupper(letter)) - 65] &lt;&lt; endl;
        }          // outputs phonetic alphabet based on alphabetical value
        else if (letter == &quot; &quot;);
        {
             cout &lt;&lt; &quot;*SPACE*&quot; &lt;&lt; endl;
             word = word.substr(x, word.length());
             x = 0;   
        }
        else
        {
        cout &lt;&lt; letter &lt;&lt; &quot; is not a letter&quot; &lt;&lt; endl;
        break; // declares not a variable and ends the &#39;for&#39; loop
        }
    }
    cout &lt;&lt; &quot;Press the ENTER key to continue...&quot; &lt;&lt; endl;
    cin.ignore(1,&#39;&#92;x10&#39;);
    while(!(cin.get() &gt; 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.


GTADarkDude's Avatar
Member
0 0

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.


Xunxen's Avatar
Member
0 0

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.

ghost's Avatar
0 0

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 &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;ctype.h&gt;
using namespace std;

int main ()
{
    string phonetic[] = { &quot;Alpha&quot;, &quot;Bravo&quot;, &quot;Charlie&quot;, &quot;Delta&quot;, &quot;Echo&quot;,
                                &quot;Foxtrot&quot;, &quot;Golf&quot;, &quot;Hotel&quot;, &quot;India&quot;, &quot;Juliet&quot;,
                                &quot;Kilo&quot;, &quot;Lima&quot;, &quot;Mike&quot;, &quot;November&quot;, &quot;Oscar&quot;,
                                &quot;Papa&quot;, &quot;Quebec&quot;, &quot;Romeo&quot;, &quot;Sierra&quot;, &quot;Tango&quot;,
                                &quot;Uniform&quot;, &quot;Victor&quot;, &quot;Whiskey&quot;, &quot;X-ray&quot;,
                                &quot;Yankee&quot;, &quot;Zulu&quot; };
    string word;
    char letter;
    
    
    
    cout &lt;&lt;&quot;Input a word or sentence to be output in phonetic form:&quot; &lt;&lt; endl; 
    getline(cin, word);

    
    for(int x = 0; x &lt; word.length(); x++)
    {
        letter = word.at(x); // gets each letter by itself
        if (isalpha(letter)) // checks to make sure an alphabetical symbol
        {
             
             cout &lt;&lt; phonetic[(toupper(letter)) - 65] &lt;&lt; endl;
        }          // outputs phonetic alphabet based on alphabetical value
        else if (letter == &#39; &#39;)
        {
             cout &lt;&lt; &quot;*SPACE*&quot; &lt;&lt; endl; // places a space wherever one is
             word = word.substr(x, word.length());
             x = 0;   
        }
        else
        {
        cout &lt;&lt; letter &lt;&lt; &quot; is not a letter&quot; &lt;&lt; endl;
        break; // declares not a variable and ends the &#39;for&#39; loop
        }
    }
    cout &lt;&lt; &quot;Press the ENTER key to continue...&quot; &lt;&lt; endl;
    cin.ignore(1,&#39;&#92;x10&#39;);
    while(!(cin.get() &gt; 0)) {} // pauses at the end
    return 0;
}```

Xunxen's Avatar
Member
0 0

instead of doing this:

x=0;```
wouldn&#39;t it be better to just leave the string as it is? that way you have less overhead from the substring method.

ghost's Avatar
0 0

fixed, thanks. anyone know why i still have to press enter twice at the end to close it? Maybe if I changed to a loop where I could keep inputting new strings until I type # or some symbol like it.


GTADarkDude's Avatar
Member
0 0

You can safely remove your cin.ignore() now. getline() discards the newline symbol at the end, so in this case it also empties your input buffer. And hey, surprise, you only have to press enter once now… ;-)


ghost's Avatar
0 0

Why use while-loop for pause? Why not:

cin.get();```

j4m32's Avatar
Member
0 0

I'd given him a bit of a crap C++ conversion from what I've used in C.

I honestly didn't know about cin.sync();, sorry about that…

Jim,


ghost's Avatar
0 0

Don't worry about it;) Just thought it might come in handy.

Edit: oh yeah, I don't know what you wanted to do with: markupcin.ignore(); (I only read the last page) but what cin.sync() effectively does is discard all unread characters in buffer.


Xunxen's Avatar
Member
0 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 &lt;&lt; phonetic[toupper(word.at(x))] &lt;&lt; endl; seems much neater than

cout &lt;&lt; phonetic[(toupper(letter)) - 65] &lt;&lt; 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 &#39;A&#39; would be 13, so your phonetic array would have to start with &quot;Alpha&quot; in the 13th index, then &quot;November&quot; would be in the 0th index. it could be fun just to see how much you could confuse your teacher with that...