0

I have a switch statement menu with the following requirements:

  • "GetNewMatrix " as an enumeration option with being a number from 0 to 9.

  • The users input MUST be all on one line.

  • Enumeration MUST be used.

I need the user to be able to input something like "GetNewMatrix 5" and have the switch statement see the GetNewMatrix to initiate that case as well as pass the 5 down into the case for initialization of matrix[5].MatrixType()

I'm quite lost on how exactly to implement this. I currently have the following (quite rough) code down though this does not help me extract the users integer from their input as it needs to be done in all one line as stated above.

  • matrix is an array of size [10] of Class MatrixType which holds int values[MAX_ROWS][MAX_COLS], int numRows, and int numCols

  • input is a string used to get the users input and compare it to enum cases to decide what case to go forward with

  • name is an integer that is between 0 and 9 and used to label the Matrix in an array of [10]

  • r is an integer used to save the user specified row count

  • c is an integer used to save the user specified column count

    enum Choice {Start, GetNewMatrix, AddMatrices, SubMatrices, MultiplyMatrices, PrintMatrix, Quit};
    Choice ch = Start;
    
    while(ch != Quit)
    {
        cout << "=======================================================" << endl;
        cout << "GetNewMatrix # (Create a new Matrix)" << endl;
        cout << "AddMatrices # # # (Adds two matrices together)" << endl;
        cout << "SubMatrices # # # (Subtracts a second matrix from the first)" << endl;
        cout << "MultiplyMatrices # # # (Multiplies two matrices together)" << endl;
        cout << "PrintMatrix # (Print out a matrix)" << endl;
        cout << "Quit (Quit the program)" << endl;
        cout << "=======================================================" << endl << endl;
        cout << "Please enter your choice here: ";
    
        cin >> input; //Unable to assign ch to a string
        if (input == "GetNewMatrix")
        { 
            ch = GetNewMatrix;
        } 
        else
        if (input == "Quit") 
        {
            ch = Quit;
        } 
        else 
        {
            cout << "Unknown entry. Please use exact capitalization." << endl;
        }
    
        switch(ch)
        {
            case GetNewMatrix: //Placeholder until integer extraction is figured out
                cout << "Please enter a value (between 0 and 9) to name the matrix: ";
                cin >> name;
                matrix[name].MatrixType();
                cout << "Matrix " << name << " created." << endl;
    
                cout << "Please enter values (between 1 and 10) for row and column size: ";
                cin >> r >> c;
                matrix[name].SetSize(r - 1,c - 1);
                cout << "Matrix size set to " << r << " x " << c << endl; 
    
    
                break;
    
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Sevrene
  • 53
  • 5
  • Please include definition of `input`, `matrix`, `name`, `r` and `c`? – Kunal Puri Jan 25 '19 at 01:04
  • *The users input MUST be all on one line.* effectively says you can't use `cin >> input;` very easily as `>>` discards the end of line as whitespace. Use [`std::getline`](https://en.cppreference.com/w/cpp/string/basic_string/getline) with a [`std::istringstream`](https://en.cppreference.com/w/cpp/io/basic_istringstream) instead. [See this answer for inspiration](https://stackoverflow.com/a/7868998/4581301). – user4581301 Jan 25 '19 at 01:06
  • Please include definition of `input` also. Is it defined as `std::string` or something else? – Kunal Puri Jan 25 '19 at 01:11
  • 1
    Unrelated: Rather than explaining what's missing from code, add the missing code. – user4581301 Jan 25 '19 at 01:11
  • Unrelated: It's really hard to get code right if you don't know how you are going to so something as important as reading the input. Instead of blocking out the code and trying to beat it until it works, make little throw-away experiments you can use to figure out how to read and process a line. Then write the program around the results of those experiments. Odds are good that by the time you get what you have working you'll have thrown everything out two or three times or spend a disproportionate amount of time trying to save bad logic. Start with something small that works. Build from there. – user4581301 Jan 25 '19 at 01:13
  • In this case if you follow the [advice of option 2 in this answer](https://stackoverflow.com/a/7868998/4581301) you can salvage a great deal of your code. Just replace `cin` with the `istringstream` holding the line you got from the user with `getline`. – user4581301 Jan 25 '19 at 01:17

2 Answers2

0

As you may now behind the seen enum is working like an array index which start from 0 and so on so inseted of using char make your char ch; variable to int like this int ch; and then you can take input in int for choice and put it into switch as 0 to 9 according to input you case will run.

Usman Ghani Mughal
  • 613
  • 2
  • 7
  • 14
0

Using the info of User4581301 (Thank you for the other post as well as the added info) I got the following to work for me:

int main()
{
string input;
int count = 0;
int i;
int j;
int item;
int num1;
int num2;
int num3;
string case_value;
int r; //used for row size
int c; //used for column size
MatrixType matrix[10];

enum Choice {Start, GetNewMatrix, AddMatrices, SubMatrices, MultiplyMatrices, PrintMatrix, Quit};
Choice ch = Start;

while(ch != Quit)
{
    cout << "=======================================================" << endl;
    cout << "GetNewMatrix # (Create a new Matrix)" << endl;
    cout << "AddMatrices # # # (Adds two matrices together)" << endl;
    cout << "SubMatrices # # # (Subtracts a second matrix from the first)" << endl;
    cout << "MultiplyMatrices # # # (Multiplies two matrices together)" << endl;
    cout << "PrintMatrix # (Print out a matrix)" << endl;
    cout << "Quit (Quit the program)" << endl;
    cout << "=======================================================" << endl << endl;
    cout << "Please enter your choice here: ";

    if(count > 0)
    {
        cin.ignore();
    }
    getline(cin, input);
    istringstream copy;
    copy.str (input);

    count++;

    copy >> case_value;
    copy >> num1; //value used in the first # of EACH case if it has one
    copy >> num2; //value used in the second # of EACH case if it has one
    copy >> num3; //value used in the third # of EACH case if it has one

    if (case_value == "GetNewMatrix")
    { 
        ch = GetNewMatrix;
    } 
    else
    if (case_value == "PrintMatrix")
    {
        ch = PrintMatrix;
    }
    else
    if (case_value == "Quit") 
    {
        ch = Quit;
    } 
    else 
    {
        cout << "Unknown entry. Please use exact capitalization." << endl;
    }

    switch(ch)
    {
        case GetNewMatrix: 
        {
            cout << "Matrix " << num1 << " obtained." << endl;

            cout << "Please enter values (between 1 and 10) for row and column amount: ";
            cin >> r >> c;
            matrix[num1].SetSize(r,c);
            cout << "Matrix size set to " << r << " x " << c << " reading up->down then left->right." << endl; 

            i = 0;
            while (i < c)
            {
                cout << "Please enter the " << r << " value(s) for column " << i + 1 << " separated by spaces: ";
                cin.ignore();
                getline(cin, input);
                istringstream copy;
                copy.str (input); 

                for (j = 0; j < r; j++)
                {
                    int temp;
                    copy >> temp;
                    matrix[num1].StoreItem(temp, i, j);
                }
                i++;
            }
            break;
        }
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Sevrene
  • 53
  • 5
  • Careful with that `cin.ignore()`. `std::getline` doesn't leave much you need to `ignore`, and when you do have to `ignore` do it shortly after the operation that leaves stuff in the stream that you need `ignore`ed, not before the next operation. This eliminates the possibility there won't be anything to `ignore` if you `ignore` just in case and it keeps the cause and the cure close together and thus easier to keep in your head. Side note: `istringstream copy; copy.str (input);` can be `istringstream copy(input);` I'm not sure this saves much at runtime, but it is less to type, – user4581301 Jan 25 '19 at 05:43
  • If you want to mess with your teacher's head (assuming you have a teacher) you can replace the `if (case_value == "blah blah blah") { ch = PrintMatrix; }` with a [`std::map choicemap{ {"Start", Start}, {"GetNewMatrix",GetNewMatrix}, etc... };`](https://en.cppreference.com/w/cpp/container/map) that maps the strings to the enums. This lets you `ch = choicemap.at(case_value);`. It also makes it easy to extend the possibilities by adding an enum and an entry in the `map`. – user4581301 Jan 25 '19 at 05:54
  • And that leads to a `map` of strings to functions so that you don't need the `enum` or the `switch`, but that's getting way outside the scope of the assignment. – user4581301 Jan 25 '19 at 05:55
  • Always use .equals to compare strings. Eg: case_value.equals("") = = 0 – Leni Jan 25 '19 at 05:58