tags:

views:

128

answers:

4

Hey guys, So my assignment is to create multiple classes for a Person, Name, ID #, Address, and Phone #.

Name makes up: First, Middle, and Last name. ID # makes up: 9 digits. Address makes up: street, city, state, and 5 digit zip code. Phone # makes up: 3 digit area code and 7 digit number. Person makes up: a full Name (First, Middle, Last), an Address, a Phone # (area code, and number), and a ID # (9 digit number).

I have accomplished all of this. My problem is we are also supposed to make a menu, to specify how many people the user wishes to type in, where they want to save the file, if they want to read or write to a file specified by the user, and being able to sort the people by name (last, first, or middle) or by ID #, and save the sorted list to a user specified file.

I have all the code written, but my write function is not working for some reason. What happens is I run the program, the menu I created pops up. I select '1' enter the file, then the menu pops up again, and I select '2' to make sure it cant read since there is nothing in the specific file I am testing with. Next, I select '3' to write People to the user specified file. It prompts me for how many People I want to enter and I enter a number (2). Then the prompt for typing in the first name pops up and I get some error saying "an unhandled win32 exception occured" in my project .exe...

Here is my code:

//global variables
char filename[256];
fstream file2 (filename);

int r;
Person * stuArrPtr=new Person[r];

int w;
Person * stuArrPtr2=new Person[w];

//global functions
void WriteUserFile () {
//write as many ppl as specified to a file...
// int w;
 cout << "How many students would you like to enter?: ";
 cin  >> w;

// Person * stuArrPtr2=new Person[w];
 if (!file2.is_open ()) {
  cout << "File did not open" << endl;
  file2.clear ();
  file2.open (filename, ios_base::out);
  file2.close ();
  file2.open (filename, ios_base::out | ios_base::in);

 }
 else {
  for (int i = 0; i < w/*!file2.eof ()*/; i++) {
   stuArrPtr2[i].InputPerson();
   if (strcmp(stuArrPtr2[i].PersonNam.GetFirst(), "EOF") != 0)
    stuArrPtr2[i].Display (file2);
  }
 }
 cout << endl;
// delete [] stuArrPtr2;
}

void Menu () {
 int option;
 do {
  //display menu
  cout << " Type '1' - to open a file for reading or writing" << endl << endl;
  cout << " Type '2' - to read from the file you specified in '1'" << endl << endl;
  cout << " Type '3' - to write from the file you specified in '1'" << endl << endl;
  cout << " Type '4' - sort students by last name" << endl << endl;
  cout << " Type '5' - sort students by first name" << endl << endl;
  cout << " Type '6' - sort students by middle name" << endl << endl;
  cout << " Type '7' - sort students by ID number" << endl << endl;
  cout << " Type '8' - exit" << endl << endl;
//  cout << " Enter appropriate number here: [ ]\b\b";
  cout << " Enter appropriate number here: ";
  cin >> option;

  switch(option) {
   case 1:
    cout << "you entered option 1" << endl;
    OpenUserFile ();
    break;
   case 2:
    cout << "you entered option 2" << endl;
    ReadUserFile ();
    break;
   case 3:
    cout << "you entered option 3" << endl;
    WriteUserFile ();
    break;
   case 4:
    cout << "you entered option 4" << endl;
    SortLastName ();
    break;
   case 5:
    cout << "you entered option 5" << endl;
    SortFirstName ();
    break;
   case 6:
    cout << "you entered option 6" << endl;
    SortMiddleName ();
    break;
   case 7:
    cout << "you entered option 7" << endl;
    SortIDNumber ();
    break;
   case 8:
    cout << "you entered option 8" << endl; //exit
    delete [] stuArrPtr;
    delete [] stuArrPtr2;
    break;
   default:
    cout << "you screwed up, no big deal, just try again!" << endl;
  } //end switch
  //if (option == 6) {
  // break;
  //}
 } while (option != 8);
// system("pause"); 
}

void main () {
Menu ();
}
/////////////////END OF CODE///////

Sorry the code is so long, and any help is very, very much appreciated!

A: 

what stuArrPtr2[i].Display (file2); is doing ?

also you don't have a better way to remember the last person ?

if (strcmp(stuArrPtr2[i].PersonNam.GetFirst(), "EOF") != 0)

like number of item in the array or chained list.

RageZ
stuArrPtr2[i].Display (file2); displays the Person data to file2 which is the input file specified by the user.And no I'm not sure how else to remember the last Person...
nick
so basically stuArrPtr2[i].Display (file2); writes the Person data to the user specified input file...
nick
+1  A: 

the problem with your code are the first few lines.

int w;
Person * stuArrPtr2=new Person[w];

At program startup w is most probably initialized with 0. So you create an array of zero Persons. The moment you call stuArrPtr2[i].InputPerson() which should be stuArrPtr2[i]->InputPerson() by the way, you try to access a member function of an non existing object.

What you will have to do is create new Person objects depending on the number you just entered like stuArrPtr2 = new Person[w] within the function WriteUserFile().

Cheers Holger

Holger Kretzschmar
Ok, thank you sooo much!! That fixed it, and makes sense to me now that you pointed it out. However, now I have 1 more small problem. When I run the WriteUserFile() I enter the number of student, and it skips the first prompt (enter first name). So the first prompt I can type in is the Middle name. Why would it be skipping that first prompt (enter first name)?
nick
since I don't know what the function InputPerson() looks like it's quite hard to tell what goes wrong ;-)
Holger Kretzschmar
well thanks for all your help i fixed this problem with an additional cin.getline before the WriteUserFile() and that fixed the problem!
nick
A: 

Some hints:

  • use std::string, not arrays of char
  • do not create objects using new unless absolutely necessary
  • learn about scope - your file stream shoud not be global
  • main must return an int
  • think before writing code
anon
Well you are wrong about main, my teacher told us to do it the way I have done it above, and the way you are reffering to is considered old and bad practice... You cannot use std::string without too much effort because many of the functions I am using rquire "char *" so its really my only option... I understand the scope of my file stream should not be global, but it is the only way my code will work and I do not have time to write another class...And I really appreciate your last comment, what kind of comment is that!?
nick
I don't suppose it has occured to you that your teacher might be wrong?
anon
No, it doesnt occur to me because this is the second teacher I have had that has told me this. Also, when I visited colleges a few months ago and sat in on multiple c++ classes, all the main functions were written the way I wrote above... Even if my teacher was wrong, why does it compile and the code inside it run?
nick
Well it should occur to you, because your teachers are indeed wrong. C++ is not defined by your teachers, or by the compiler that you happen to use (I'd guess Microsoft's) but by the C++ Standard, an ISO document. And this specifies very clearly that main() must have the return type int.
anon
The main() function returns an int. Always. Whether C++ or C.See http://c-faq.com/ansi/index.html items 11.12 through 11.16.
Thomas Matthews
A: 

Try using a static array of characters for the menu and the ostream::write function. Your menus will be displayed faster:

static const char menu_text[] =
" Type '1' - to open a file for reading or writing\n"
"\n"
" Type '2' - to read from the file you specified in '1'\n"
"\n"
" Type '3' - to write from the file you specified in '1'\n"
"\n"
" Type '4' - sort students by last name\n"
"\n"
" Type '5' - sort students by first name\n"
"\n"
" Type '6' - sort students by middle name\n"
"\n"
" Type '7' - sort students by ID number\n"
"\n"
" Type '8' - exit\n"
"\n"
" Enter appropriate number here: ";

//...
    cout.write(menu_text, sizeof(menu_text) - sizeof('\0')); // Remove the nul terminator from being written.

Another benefit is that if you change the text later, you don't have to change your code or add cout statements.

Also note that the C++ compiler (or preprocessor) will concatenate strings so there is no need for a ';' until the end of the last text line.

The static and const modifiers tell the compiler to put it into a read-only section and refer to that section rather than copying it to the local stack.

Thomas Matthews