0

In the adding user section in the code below, I am unable to type any characters for the "Add another person?(y/n): " question. it just jumps back to entering age. How do I fix this?

I've tried to change ans into a string, implement a while loop to force the question to show up, and many other things. It just seems that nothing works and I've been trying it for the good part of two hours

#include <iostream>
#include <string>
#include <Windows.h>
using namespace std;

int main()
{
    char ans;
    int people;
    int option;
    int count = 0;
    struct data
    {
        string name;
        int age;
        char gender;
        string comments;
    }person[100];
    // homescreen 
homescreen:
    cout << "Welcome to the Data Base!" << endl;
    cout << endl;
    // displaying all people
    for (int list = 0; list < count; list++)
    {
        cout << list << ".) " << person[list].name << endl;
    }
    cout << endl;
    cout << "[1] View Person" << endl;
    cout << "[2] Add Person" << endl;
    cout << "[3] Edit Person" << endl;
    cout << "[4] Delete Person" << endl;
    cout << "[5] Exit" << endl;
    cout << "Choose Option: ";  cin >> option;
    // using options
    while (option != 5)
    {
        if (option == 1)
        {
        view:
            for (int list2 = 0; list2 < count; list2++)
            {
                cout << list2 << ".) " << person[list2].name << endl;
            }
            cout << endl;
            cout << "Enter number of person you want: ";  cin >> people;

            system("cls");
            cout << "Name: " << person[count].name << endl;
            cout << "Age: " << person[count].age << endl;
            cout << "Gender: " << person[count].gender << endl;
            cout << "Comments: " << person[count].comments << endl << endl;

            cout << "View another person?(y/n): ";      cin >> ans;
            if (ans == 'y')
            {
                system("cls");      goto view;
            }
            else if (ans == 'n')
            {
                system("cls");      goto homescreen;
            }
        }
        if (option == 2)
        {
        add:
            system("cls");
            cout << "Name: ";  cin >> person[count].name;

            system("cls");
            cout << "Age: ";  cin >> person[count].age;

            system("cls");
            cout << "Gender(M/F/H): ";  cin >> person[count].gender;

            system("cls");
            cout << "Comments: ";  cin >> person[count].comments;

            count++;
            system("cls");
            cout << "Add another person?(y/n): ";   cin >> ans;

            if (ans == 'y')
            {
                system("cls");
                goto add;
            }
            else if (ans == 'n')
            {
                system("cls");
                goto homescreen;
            }
        }
    }
}

If you anybody can help me I'd be grateful

JeJo
  • 30,635
  • 6
  • 49
  • 88
  • 1
    A note about the question title. It is implied. Very few people ask questions here when they are able to solve the problem unless they intend to immediately self-answer. A good question has a title that briefly describes the problem, or at least your understanding of it, so that future askers with similar problems can find the question and it's answers. – user4581301 Nov 16 '18 at 05:42
  • 1
    Get familiar with the debugging tool that comes with your development environment. Being able to step through trouble spots in a program to see exactly what the program does will crack a problem like this wide open. – user4581301 Nov 16 '18 at 05:47

2 Answers2

2
  1. The goto statements in your code makes the program really good spaghetti structure and that is not good.

    Therefore, think instead of goto other options, such as infinite while loop which will break once the user enters the n or moving the code to the function.

  2. Secondly what if you have not entered any persons and choosing the option 1. You still output the attributes of the person as count is initialized zero at least. Remember the attributes are not initialized at this point. Accessing the uninitialized variables will invoke undefined behavior. Therefore, provide a check (something like if(count > 0) )before you execute the code in option 1.

  3. In addition to that, remember that std::endl flushes the output buffer, and '\n' doesn't. Therefore, most of the cases you might wanna use just \n.

  4. Last but not the least, use std::vector instead of the using C style arrays with some predefined size. What if the user has more than 100 inputs? The solution in C++ is std::vector, which can expand dynamically as its storage is handled automatically.

Following is a possible solution to your program, in which the comments will guide you through to the things that I mentioned above.

#include <iostream>
#include <string>
#include <vector>
#include <windows.h>

struct Data
{
    std::string name;
    int age;
    char gender;
    std::string comments;
    Data(const std::string& n, int a, char g, const std::string& c) // provide a Constructor
        :name(n), age(a), gender(g), comments(c)
    {}
};

void debugMsg(const std::string& msg)
{
    system("cls");
    std::cout << "\n\n\t\t" << msg << "\n\n";
    Sleep(3000);
}

int main()
{
    std::vector<Data> person; // use std::vector to store the datas
    while (true)  // loop: 1
    {
        system("cls");
        std::cout << "Welcome to the Data Base! \n\n";
        std::cout << "[1] View Person\n";
        std::cout << "[2] Add Person\n";
        std::cout << "[3] Edit Person\n";
        std::cout << "[4] Delete Person\n";
        std::cout << "[5] Exit\n";
        std::cout << "Choose Option: ";  
        int option;  std::cin >> option; 
        switch (option) // use switch to validate the options
        {
        case 1:
        {
            while (true)   // loop - 2 -> case 1
            {
                // if no data available to show -> just break the loop 2 and return to the outer loop(i.e, loop 1) 
                if (person.empty()) { debugMsg("No person available to show ....going to main manu...."); break; }
                // otherwise: displaying all people
                for (std::size_t index = 0; index < person.size(); ++index) 
                    std::cout << index << ".) " << person[index].name << "\n";
                std::cout << "\nEnter number of person you want: ";  
                std::size_t index;  std::cin >> index;
                // if the index is not valid -> just break the loop 2 and return to the outer loop(i.e, loop 1) 
                if (index < 0  || index >= person.size()) { debugMsg("Sorry, wrong index!... returning to the main menu......");  break; }
                system("cls");
                std::cout << "Name: " << person[index].name << std::endl;
                std::cout << "Age: " << person[index].age << std::endl;
                std::cout << "Gender: " << person[index].gender << std::endl;
                std::cout << "Comments: " << person[index].comments << std::endl << std::endl;
                std::cout << "View another person?(y/n): ";      
                char ans;  std::cin >> ans;
                if (ans == 'y') { system("cls");    continue; } // just continue looping
                else if (ans == 'n') { break; }                 // this will break the loop 2 and return to the outer loop(i.e, loop 1)                 
                else { debugMsg("Sorry, wrong option!... returning to the main menu......");  break; }
            }
        } break;
        case 2:
        {
            while (true)   // loop - 3 -> case 2
            {
                system("cls");
                std::string name, comments; int age; char gender;
                std::cout << "Name: ";           std::cin >> name;
                std::cout << "Age: ";            std::cin >> age;
                std::cout << "Gender(M/F/H): ";  std::cin >> gender;
                std::cout << "Comments: ";       std::cin >> comments;
                // simply construct the Data in person vector in place
                person.emplace_back(name, age, gender, comments);
                std::cout << "\n\nAdd another person?(y/n): ";
                char ans;  std::cin >> ans;
                if (ans == 'y') { system("cls"); continue; }
                else if (ans == 'n') { system("cls"); break; } // same as case 1
                else { debugMsg("Sorry, wrong option!... returning to the main menu......"); break; }
            }
        } break;
        case 3: { /*code*/ debugMsg("Sorry, Not implemented!... returning to the main menu......"); } break;
        case 4: { /*code*/ debugMsg("Sorry, Not implemented!... returning to the main menu......"); } break;
        case 5: return 0; // if its 5, just retun the main
        default: break;
        }
    }
    return 0;
}
JeJo
  • 30,635
  • 6
  • 49
  • 88
1

As mentioned above, using "goto" is a bad style, so i would suggest structure your program a little. Below is my version. Naturally, I did not add any checks and controls, the author will be able to do this on his own. But main logics should work. And, of course, it is better to use vector instead of static array.

#include <iostream>
#include <string>
#include <Windows.h>
using namespace std;

enum options { OPT_VIEW = 1, OPT_ADD = 2, OPT_EDIT = 3, OPT_DELETE = 4, OPT_EXIT = 5 };

struct data
{
    string name;
    int age;
    char gender;
    string comments;
};

class App
{
private:
    data person[100];
    int  count = 0;
public:  
    App();
    void Run();
    int HomeScreen();
    void View();
    void Add();
};

App::App() : count(0)
{}

void App::Run()
{
    int option = HomeScreen();
    while(option != OPT_EXIT)
    {
        switch(option)
        {
        case OPT_VIEW:
            View();
            break;
        case OPT_ADD:
            Add();
            break;
        }
        option = HomeScreen();
    }
}

int App::HomeScreen()
{
    int option = 0;
    cout << "Welcome to the Data Base!" << endl;
    cout << endl;
    // displaying all people
    for(int list = 0; list < count; list++)
    {
        cout << list << ".) " << person[list].name << endl;
    }
    cout << endl;
    cout << "[1] View Person" << endl;
    cout << "[2] Add Person" << endl;
    cout << "[3] Edit Person" << endl;
    cout << "[4] Delete Person" << endl;
    cout << "[5] Exit" << endl;
    cout << "Choose Option: ";  cin >> option;
    return option;
}

void App::View()
{
    char ans = 0;
    do
    {
        int people = 0;

        for(int list2 = 0; list2 < count; list2++)
        {
            cout << list2 << ".) " << person[list2].name << endl;
        }
        cout << endl;
        cout << "Enter number of person you want: ";  cin >> people;

        system("cls");
        cout << "Name: " << person[people].name << endl;
        cout << "Age: " << person[people].age << endl;
        cout << "Gender: " << person[people].gender << endl;
        cout << "Comments: " << person[people].comments << endl << endl;

        cout << "View another person?(y/n): ";      cin >> ans;
    }
    while(ans == 'y');

    system("cls");
}

void App::Add()
{
    char ans = 0;
    do
    {
        system("cls");
        cout << "Name: ";  cin >> person[count].name;

        system("cls");
        cout << "Age: ";  cin >> person[count].age;

        system("cls");
        cout << "Gender(M/F/H): ";  cin >> person[count].gender;

        system("cls");
        cout << "Comments: ";  cin >> person[count].comments;

        count++;
        system("cls");
        cout << "Add another person?(y/n): ";   cin >> ans;
    }
    while(ans == 'y');

    system("cls");
}

int main()
{
    App program;
    program.Run();
}
snake_style
  • 1,139
  • 7
  • 16