C/C++ Solving C++ Programing Issues: Create & View Person Data

  • Thread starter Thread starter faust9
  • Start date Start date
  • Tags Tags
    C++
AI Thread Summary
The discussion revolves around a programming issue in a C++ class project where the user is trying to create a program that allows for the creation and viewing of a fictional person’s information. The core problem identified is that the program fails to retain the user-inputted name and age after the creation of the person object. The user initially suspects the issue lies with the `getline(cin, name)` function, but it is later revealed that the problem arises from the instantiation of the `person` object within a loop. Each time the loop iterates, a new `person` object is created, which resets the name and age to their default values. The solution involves moving the instantiation of the `person` object outside of the loop, allowing the program to retain the data entered by the user. This change resolves the issue, enabling the program to function as intended.
faust9
Messages
690
Reaction score
2
Ok, I've been programming with C on and off for a while but I decided to take a C++ class to learn something new. We finally got to classes, and strings which are plaguing me to no end. Here's the problem, I have to write at program which creates a blank person a compile time. The software user will then enter the required information (name and age) for the fictional person. The user will then have the option to view the created person. The user may not view the created person until the initial data has been entered(not too worried about this part.

My problem is my program asks for the name and age but only the ag updates. Also, if I include a constructor the program won't replace the information supplied by the constructor. I'd like to set the default age to zero to act as the flag for the verification process. Anyway, here's the code:


main[/size]
Code:
#include "stdafx.h" //basic run of the mill include
#include "menu.h"   //required to create menus
#include "person.h" //header file which supplies the person class
  
int main()
  {
    Menu personMaker;   //creates a new menu object.
    int selection;     //used to determine which menue item was selected  
    
    //three menu line items created by using the menu class.
    personMaker.addItem ("Create a person");
    personMaker.addItem ("View person information");
    personMaker.addItem ("I bid thee a fond farewell");
    
    
    //loop used to allow person creations.
    do
      {
        //menu title
        personMaker.displayMenu("David T Platt's Homework Extravaganva");
        selection= personMaker.getChoice(); //gets menu input from user.
        
        person hwPerson; //creates instance of person.
      
        //used to select which function to call
        switch (selection)
          {
            case 1:
              {
                hwPerson.getdata(); //calls function for daata input
                break;
              }
            case 2:
              {
                hwPerson.showdata(); //calls function for data output
                break;
              }
            case 3:
              {
                break;
              }
          }
      }while(selection !=3);
 
    return 0;
  }

person.h[/size]
Code:
//obligatory includes
#include "stdafx.h"


class person
  {
    private:
    int age;
    string name;
    
    public: 
    void getdata();
    void showdata();
    person();
  };

person.cpp[/size]
Code:
//obligatory includes
#include "stdafx.h"
#include "person.h"

person::person() : age(0), name("nonoame")
  {
  }
  
void person::getdata()
  {
    cout << "\nHow old is this person? ";
    cin >> age;
    cout << "Please enter the name of the person you would like to create: ";
    cin.ignore(10, '\n');
    getline(cin, name);
    return;
  }
  
void person::showdata()
  { 
    /*if (age==0)
      {
          cout << "Sorry please enter the information prior to viewing it:";
          return;
       }*/
    cout << name << " is " << age;
    return;
  }

I commented out the verification portion. It should work (shouldn't it?).

stdafx.h[/size]
Code:
#include <iostream>
#include <tchar.h>
#include <string>
#include <conio.h>

using namespace std;

I have a menu class that works so I'm not going to post that code.

I think my problem with the name portion is with the getline(cin, name) function. Am I using it correctly? It's new to me, so I'm probably way out in left field.

here's th output:

Code:
                        1)  Create a person

                        2)  View person information

                        3)  I bid thee a fond farewell

                        Enter Choice: 1

How old is this person? 25
Please enter the name of the person you would like to create: monty python


                        1)  Create a person

                        2)  View person information

                        3)  I bid thee a fond farewell

                        Enter Choice: 2
nonoame is 0

                        1)  Create a person

                        2)  View person information

                        3)  I bid thee a fond farewell

                        Enter Choice:

Notice how the age didn't update not the name either. I'm using gcc, mingw on my wifes XP box because the class I'm taking requires win32 console apps.

Thanks for any help BTW.
 
Technology news on Phys.org
(The first thing I might do is to put debugging code in the "getdata" function, just to make sure the variables are being set)

There's an exercise you can sometimes do by hand to spot logic errors. You know that something is going wrong between the time you return from "getdata" and the time you call "showdata". Can you tell me everything that happens between those two functions?
 
Yeah, I already did that. Should've mentioned it...

Right after getline, I had:

cout << name <<'\n'<< age;

and it showed the correct stuff. The name I entered. The problem seems that name is given function scope within the getdata function for some weird reason while age (if there is no constructor) is give a scope within the person class.
 
Hurkyl said:
(The first thing I might do is to put debugging code in the "getdata" function, just to make sure the variables are being set)

There's an exercise you can sometimes do by hand to spot logic errors. You know that something is going wrong between the time you return from "getdata" and the time you call "showdata". Can you tell me everything that happens between those two functions?

I don't understand the question "between the two". The only thing I have going on that I didn't include was the menu class which centers the menu in the console.

here, the menu class.cpp
Code:
#include<iostream.h>				// For cin, cout
#include<windows.h>					// For Message box stuff
#include<fstream.h>					// For ofstream operations
#include<ctype.h>					// For data validation
#include "menu.h"					// For menu declarations


// Default Constructor for menu class initalizes maxItems to zero
Menu::Menu(): maxItems(0)  { }

// Displays the menu to the screen
void Menu::displayMenu(char* title)
{
	cout<<"\n\t\t\t****** "<<title<<" ******\n\n";
	for (int i=1; i <= maxItems; i++)
		cout <<"\n"<<"\t\t\t"<< i << ")  "<< titles[i] << endl;
}

// Adds 1 new menu item
void Menu::addItem(char *menuItem)
{
	titles[++maxItems] = menuItem;
}

// Private function that validates the user response
// Note: The funky logic.  What happens is in the get function
// We pass wht the user entered, (char) to this function
// cast into a integer.  When that happens we get the ASCII
// code for the input.  Since we know that the ASCII integers
// start at 48, and we know that they are contiguios, the 
// formula was designed to convert back to an integer (1-9),
int Menu::valid(int check)
{
	if (check > 48 && check <= maxItems+48)
		return (check - 48);
	else
	{
		MessageBeep(MB_ICONHAND);
		MessageBox (NULL, "You typed in a wrong choice.", "Entry Error!", MB_ICONWARNING);
		cin.clear();
		cin.ignore(10, '\n'); //prevents cin from running menu off screen for
		return(-1);			  //users that type words instead of number
	}

}

// Gets the choice from the user until valid.  Accepts as
// a char and type casts it to an integer for checking
// When cc is returned it will be a number [1-9]
int Menu::getChoice()
{
	char choiceIn;		// Variable that holds what the user entered
	int convertedChoice; // Variable that holds the converted integer
		do {
			cout << "\n\t\t\tEnter Choice: ";
			cin >> choiceIn;

			convertedChoice=valid(int(choiceIn));

		}while (convertedChoice < 0);

			return convertedChoice;
}

and .h
Code:
#ifndef _MENU_H
#define _MENU_H

class Menu 
{
public:
	Menu();										// Default Constructor for menu
	void addItem(char *menuItem);				// Add Menu Item
	void displayMenu(char*);							// Display Function
	int getChoice();							// Get user Choice Function
	int getMaxItems()  {return (maxItems);}		// Returns the number of menu items
private:										
	int valid(int check);						// Validates user's choice
	char *titles[10];							// Array of pointer for hold menu options
	int maxItems;								// number of menu items
};

#endif

Am I using getline() correctly? Do I have to change the scope of some variable(I hate these object things BTW)?
 
Well, let me get you started:

The program return from "getdata".
The program executs "break"
The program tests "selection != 3"
...

Can you carry it from here?
 
Ok,

Instance of menu class created
Menu items passed to menu class

do/while loop entered to allow for multiple iterations.

Title passed to menu class
personMaker menu is called with user input stored in selection variable
instance of person class created with age=0 and name"noname" as constructor arguments


switch tests selection

case 1:
getdata function is called
user is asked for age
user inputs age using cin
user asked for name
cin buffer is cleared
getline(cin, name) reads input from keyboard buffer and stores output to name
getdata returns to do/while loop
case 1 break

while test selection !=3
since selection was one, do while called again...

Ah I see says the blind man to the deaf mute... I have my class person call withing the do/while loop thus reinitializing it with each iteration.

Pretty clever...

moved offending chunk and viola! we have a working pgm!

Thanks a bunch.
 
So the problem was this:

person hwPerson; //creates instance of person.

being in the loop, right?
 
Back
Top