I have a homework assignment that deals with creating a command line menu, and then selecting items from that menu that do something. the items need to be selected by using either a lowercase or uppercase letter that represents that specific menu item. for example, if i want to print a sentence, then i need to type either lowercase 'p' or uppercase 'P'. right now i dont want help getting each menu item to work, but i need help with configuring my program so that when i type p or P, it will do that function, or if i select e or E, it will perform that function...etc. this is the code I have right now, I was wondering if someone could tell me if I am on the right track. right now i was thinking of declaring each valid character for input as a character, and then inputing that character. i then made a simple if/else statement to test if it works. thanks for any help you can give me.

#include <iostream>

using std::cout;
using std::cin;
using std::endl;

int main()
{
    char x [1];
    char c [1];
    char C [1];
    char p [1];
    char P [1];
    char e [1];
    char E [1];
    char d [1];
    char D [1];
    char q [1];
    char Q [1];

    cout << "You can perform the following tasks: \n";
    cout << "(p) Print a Sentence \n";
    cout << "(c) Capitalize the Sentence \n";
    cout << "(e) Encode the Sentence \n";
    cout << "(d) Decode the Sentence \n";
    cout << "(q) Quit \n";
    cout << "Please Select one... \n";

    cin.getline (x, 1);

        if (x = c || x = C)        //if you type either lowercase c or uppercase C, test was successful
            cout << "Test Successful /n";

        else {
            cout << "Test Failed /n";
        }

return 0;
}

Recommended Answers

All 18 Replies

Member Avatar for iamthwee
I have a homework assignment that deals with creating a command line menu, and then selecting items from that menu that do something.  the items need to be selected by using either a lowercase or uppercase letter that represents that specific menu item.  for example, if i want to print a sentence, then i need to type either lowercase 'p' or uppercase 'P'.  right now i dont want help getting each menu item to work, but i need help with configuring my program so that when i type p or P, it will do that function, or if i select e or E, it will perform that function...etc.  this is the code I have right now, I was wondering if someone could tell me if I am on the right track.  right now i was thinking of declaring each valid character for input as a character, and then inputing that character.  i then made a simple if/else statement to test if it works.  thanks for any help you can give me.

    #include <iostream>

    using std::cout;
    using std::cin;
    using std::endl;

    int main()
    {
        char x [1];
        char c [1];
        char C [1];
        char p [1];
        char P [1];
        char e [1];
        char E [1];
        char d [1];
        char D [1];
        char q [1];
        char Q [1];

        cout << "You can perform the following tasks: \n";
        cout << "(p) Print a Sentence \n";
        cout << "(c) Capitalize the Sentence \n";
        cout << "(e) Encode the Sentence \n";
        cout << "(d) Decode the Sentence \n";
        cout << "(q) Quit \n";
        cout << "Please Select one... \n";

        cin.getline (x, 1);

            if (x = c || x = C)        //if you type either lowercase c or uppercase C, test was successful
                cout << "Test Successful /n";

            else {
                cout << "Test Failed /n";
            }

    return 0;
    }

Yes it looks ok apart from a few syntax errors.

when i build the program it gives me the following errors:

warning C4800: 'char *' : forcing value to bool 'true' or 'false' (performance warning)
error C2106: '=' : left operand must be l-value
error C2440: '=' : cannot convert from 'bool' to 'char [1]'
There are no conversions to array types, although there are conversions to references or pointers to arrays

i was wondering what was wrong with my code above that gives me these errors. i tried fiddling around with some things a bit but i cant fix it. what syntax errors do you see that I am missing?

i changed the following if statement so it has double = now:

if (x == c || x == C) //if you type either lowercase c or uppercase C, test was successful
cout << "Test Successful /n";

it gives me no errors but when i run the program and type either c or C it says test failed. why would this happen?

Hi! :)

Okay, your premise is sound, but the execution could use some work. If you don't mind me turning into an evil code reviewer, I'll point out some ways to make your code better.

using std::cout;
using std::cin;
using std::endl;

This is my personal preference. I think it's a good one because I'm good at convincing my coworkers to use it. ;) Any using statements should be at the smallest possible scope. That usually means putting a using namespace std; at the top of a bunch of functions or even in a loop or if body. You shouldn't use it globally, and the highest scope should be at the top of a namespace. Anything global should be prefixed with std:: and that's not a big problem because global things that need a standard name should be kept to a minimum. You can ignore all of this for now though, it's not really important when learning C++. :eek:

char x [1];
char c [1];
char C [1];
char p [1];
char P [1];
char e [1];
char E [1];
char d [1];
char D [1];
char q [1];
char Q [1];

You can make arrays of 1, but it doesn't really make much sense. An array of 1 char is basically a single char that's just harder to access directly. Instead of just saying x, you have to say x[0], or *x. That's a notational inconvenience.

cin.getline (x, 1);

This is the big problem. cin.getline() will read n - 1 characters and append the array with '\0'. No matter what you type, x will always be an empty string.

Stream input is really tricky. I hate it. :) But in this case you can just use cin.get() to read one character and things will work. If you add other input later on, you need to re-evaluate that assumption because it might not be true anymore. ;)

if (x = c || x = C)

There are three problems here. First, x is an array and the first character must be accessed with x[0] or *x. Otherwise you're just taking the address of the first character, and that's probably not what you were expecting. ;) Second, the = operator is assignment. You want the == operator for comparison. Finally, c and C are treated as variables, not character literals. You need to wrap them in single quotes.

Here's my take on the code.

#include <iostream>

int main()
{
  using namespace std;

  char x;

  cout << "You can perform the following tasks: \n";
  cout << "(p) Print a Sentence \n";
  cout << "(c) Capitalize the Sentence \n";
  cout << "(e) Encode the Sentence \n";
  cout << "(d) Decode the Sentence \n";
  cout << "(q) Quit \n";
  cout << "Please Select one... \n";

  cin.get( x );

  if (x == 'c' || x == 'C')
    cout << "Test Successful\n";
  else
    cout << "Test Failed\n";

  return 0;
}

Ask questions! I love helping. :)

Thank you so much for helping me with that! Now that I have that part settled I am working on the specific functions within my command line menu. I have already taken care of printing the sentence, as well as the quit option. My program is supposed to be continuous until the user actually types q or Q to terminate it. I just used a simple while(1) loop and then put in the break after they type q or Q.

My next question deals with making a capitalization function. I know that once I create the function I just have to simply insert it below an if statement and then include the actual function below the program.

What this function needs to do is capitalize the sentence the user inputs before the command line menu pops up. It needs to capitalize every character in that sentence. I was trying to look at it a couple of ways:

something like char capitalize(char), but I think that will only capitalize one specific character.

I was wondering if theres an a keyword or something that will capitalize an entire string. The string in my program I titled as 'sentence'. so i would do something like naming a function char capitalize(char), and then use that keyword on the string, and then return(sentence)? Here is my updated code thus far:

#include <iostream>

using std::cout;
using std::cin;
using std::endl;

int main()
{
    char x;
    char sentence [800];
    cout << "Enter a Sentence \n";
    cin.getline (sentence, 800);

    while (1)
    {
    cout << "You can perform the following tasks: \n";
    cout << "(p) Print a Sentence \n";
    cout << "(c) Capitalize the Sentence \n";
    cout << "(e) Encode the Sentence \n";
    cout << "(d) Decode the Sentence \n";
    cout << "(q) Quit \n";
    cout << "Please Select one... \n";

    cin.get(x);

        if (x == 'p' || x == 'P')        //if you type either lowercase c or uppercase C, test was successful
        {        
            
            cout << sentence << "\n";

        }
        else if (x == 'q' || x == 'Q')

            cout << "Thanks for using my program, goodbye! \n";
            break;
    }

return 0;
}

Thank you so much for helping me with that!

My pleasure. :)

I was wondering if theres an a keyword or something that will capitalize an entire string.

Some compilers give you a function that will do this. For example, Visual Studio supports a strupr() function in the <cstring> header.

cout << strupr( sentence ) << "\n";

But not all compilers do that, and it's not a standard function. It's up to you to determine if you're alright with the portability hit. If you aren't, C++ does support a function called toupper() in <cctype> that translates one character to its upper case equivalent. If you use that in a loop, you can fake strupr.

#include <cctype>

char *my_strupr( char *s )
{
  for ( char *p = s; *p; p++ )
    *p = toupper( (unsigned char)*p );

  return s;
}

cout << my_strupr( sentence ) << "\n";

And there are a number of ways to do that. Some people will advocate using the transform() function from <algorithm>, but that's tricky so I don't recommend it right now. ;)

Here is my updated code thus far:

I've discovered a problem. In something like a loop or an if statement that gives you the option of using braces, you need to be careful to remember that it's only an option if the block only has one statement. Here's your code, cleaned up a hair and properly indented. ;)

if (x == 'p' || x == 'P')
{        
  cout << sentence << "\n";
}
else if (x == 'q' || x == 'Q')
  cout << "Thanks for using my program, goodbye! \n";
break;

In the if part the braces are optional and you chose to add them, but in the else if part the braces are not optional if you want to break only if someone types 'q' or 'Q'. A good guideline is to always use braces until you're comfortable with when they can be ignored.

if (x == 'p' || x == 'P') {
  cout << strupr( sentence ) << "\n";
}
else if (x == 'q' || x == 'Q') {
  cout << "Thanks for using my program, goodbye! \n";
  break;
}

Thanks again! I included the function you helped me with but whenever I compile the program it gives me the following two errors:

error C3861: 'capitalize': identifier not found
error C2365: 'capitalize' : redefinition; previous definition was 'formerly unknown identifier'

I feel like something is throwing this off, possibly a syntax error. Here is my code after including my function:

#include <iostream>
#include <cctype>

using std::cout;
using std::cin;
using std::endl;

int main()
{
    char x;
    char sentence [800];
    cout << "Enter a Sentence \n";
    cin.getline (sentence, 800);

    while (1)
    {
    cout << "You can perform the following tasks: \n";
    cout << "(p) Print a Sentence \n";
    cout << "(c) Capitalize the Sentence \n";
    cout << "(e) Encode the Sentence \n";
    cout << "(d) Decode the Sentence \n";
    cout << "(q) Quit \n";
    cout << "Please Select one... \n";

    cin.get(x);

        if (x == 'p' || x == 'P')                
        {
            cout << sentence << "\n";
        }
        else if (x == 'c' || x == 'C')
        {
            cout << capitalize( sentence ) << "\n";
        }
        else if (x == 'q' || x == 'Q')
        {
            cout << "Thanks for using my program, goodbye! \n";
            break;
        }
    }

return 0;
}

//Function Definitions

char *capitalize(char *s)
{
  for ( char *c = s; *c; c++ )
    *c = toupper( (unsigned char)*c );

  return s;
}

Is the program having trouble pointing to capitalize in the function? Is that what the program error means? Thanks again for all your help!

Please use code tags (info in my signature).

The reason you're getting an error about capitalize() is that you haven't given the function a prototype. A prototype is simply a statement at the top of your program defining the functions so that the compiler knows they exist. For example, a prototype for capitalize() would look like this:

char *capitalize(char *s);

Your program works when this is added, but I noticed that you forgot to clear the input buffer, so you get an extra loop in there. Try cin.clear(), and perhaps cin.ignore() with some large number.

You are right, i just needed to include it at the top of my code. Thanks! and yes, I noticed that my code loops twice, so i tried inserting cin.clear(); in various places within my while loop but for some reason it didnt work. do I need to include something else in addition to cin.clear()?

I also have another question. My program needs to not alter the sentence string. So although my program above performs the functions in order, if i choose to capitalize the sentence but then just want to print the original sentence after, it will print the newly capitalized sentence. I need my program to capitalize the sentence and then print the original sentence whenever i want.

I was thinking that maybe I can just create another character string, called csentence. And then after the user inputs the sentence at the beginning of the program, it creates a duplicate of that sentence saved as csentence. so that when i output the capitalization function later, it uses the csentence string, instead of outputting the original sentence string. so i was thinking something like char csentence [800]; and then sentence = csentence; but when I try this it doesnt work. am I on the right track?

so i tried inserting cin.clear(); in various places within my while loop but for some reason it didnt work. do I need to include something else in addition to cin.clear()?

cin.clear() has a misleading name. It doesn't clear the contents of the stream, it clears the error flags. If there's an error on the stream, calling cin.clear() will let you read from cin again to try and fix the problem. The method used for clearing the stream contents is cin.ignore(). They're best used in a combination.

void clear()
{
  // Remove any errors
  cin.clear();

  // Remove all left over characters in the stream
  cin.ignore( [I]some big number[/I], '\n' );
}

I also have another question. My program needs to not alter the sentence string. So although my program above performs the functions in order, if i choose to capitalize the sentence but then just want to print the original sentence after, it will print the newly capitalized sentence. I need my program to capitalize the sentence and then print the original sentence whenever i want.

I was thinking that maybe I can just create another character string, called csentence. And then after the user inputs the sentence at the beginning of the program, it creates a duplicate of that sentence saved as csentence. so that when i output the capitalization function later, it uses the csentence string, instead of outputting the original sentence string. so i was thinking something like char csentence [800]; and then sentence = csentence; but when I try this it doesnt work. am I on the right track?

You're well on the right track. :) The only problem I see is that arrays are aggregate types, and you can't assign to them. To copy the contents of a string, you can use a loop.

// Only copy if sentence isn't empty
if ( sentence[0] ) {
  int i = 0;

  do
    csentence[i] = sentence[i];
  while ( sentence[i] );
}

But why do that when the C++ already gives you better options? :) A C style option is strcpy() in the <cstring> header.

strcpy( csentence, sentence );

Just make sure that csentence can hold all of the string. ;) Just as a side node, the ideal solution is to use the C++ string class. That solves a lot of awkward problems when it comes to array based strings.

Thanks again! I am still having issues with the void clear() but I can worry about that later. currently I am working on getting my encode function to work. This means that it just changes every letter in the sentence to a different ASCII character. I know if i use the following, I can change one character:

void encoding(char &);

So i was toying with doing something like before, using pointers and a for loop. so I was thinking of something like the following:

void *encode(char *t);
  {
    for (char *u = t; *u; u++ )
         u* = ? }

so I'm not sure what to make the *u pointer equal to

What's the range of the charecters you want? All ASCII charecters, or just letters? You could just do something like:

*u = ++(*u)%128;

Which would always increment 'u' to the next charecter until it reaches the end, and then it would start over. Of course this isn't very secure, but it's one way of doing it. You could always make the jumps bigger to make it harder (just a little) to crack.

it doesnt have to be just a letter, it can be any character. so does my function appear correct thus far?:

void *encode(char *t)
{
    for (char *u = t; *u; u++ )
        *u = ++(*u)%128;

        return t;
}

This should just increase each ASCII character in the sentence by 1 every time its run, correct?

It looks good, but WHY are you using a void pointer? It's a bad practice to get into using, and should only be used in a limited number of situations, becuase a void pointer eliminates any type-checking which could alert you to errors in your code. Just change "void *encode" to "char *encode" and it'll be good.

This should just increase each ASCII character in the sentence by 1 every time its run, correct?

Yes it does, and the %128 is a little math trick that makes *u reset back to 0 if it's larger than 127.

great, thanks! the function worked fine and I just made basically a duplicate to get the decode function to work. I just have one more quick question about my infinite loop.

As I've mentioned a couple of times whenever I run my program and select an option from the command menu, it will reprint the command menu twice afterwards. Someone had mentioned that I hadnt cleared my input buffer and this could be why it prints my menu twice. it has been suggested that i use

void clear()
{
  cin.clear();
  cin.ignore( some big number, '\n');
}

but I've tried inserting it in several places within my code and either a) nothing happens, or b) it messes with my code so the output doesnt look right. Is there a specific place I should be clearing the code within my while loop so it doesnt reprint the command menu twice? thanks!

Place the cin.clear() and the cin.ignore() statements after you get the input.

Thanks a lot for the help everyone! i think I got all the kinks out. appreciate everything!

Scroll back by 1 post and you'll see the answer.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.