So I've only been programming for a few weeks, and I thought that I'd learn how to program by converting a rather complicated baseball board game to a program.

I'm writing a preliminary program that stores player information from a card into a random access file. My Struct holds the player data, including several arrays that are causing the problems when I try to read a player's data from the file.

Now, this program is nowhere near finished, (I want to solve this problem before continuing). Specifically, when I try to output the final two arrays (firstCol and secCol), the first few values output fine, then I start getting a huge number (-858993460) for each value.

I suspect that there is something wrong with the writing/reading of the arrays in my Struct, but I'm really not sure how to correct this problem. I've looked into Vectors, but I'm not sure that using them would make a great deal of difference.

Note that I am doing this purely for fun and enjoyment and that I am taking/have taken no classes on C++, so my code is probably laughably bad! Here it is:

#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <fstream>
#include <stdlib.h>

using namespace std;

struct PlayerRecord {
	int pIN;
	char batSide;
	char throwSide;
	char lastName [15];
	char firstName [15];
	int posRat [9];
	int batChar;
	int lHandi;
	int rHandi;
	char stealAllow;
	int stealRat;
	int speedRat;
	int armRat;
	int cThrowRat;
	int cPBRat;
	int pSGrade;
	int pRGrade;
	int pWP;
	bool pBK;
	bool pHB;
	int pMF;
	int pHR;
	bool pK;
	bool pX;
	bool pY;
	bool pW;
	bool pZ;
	bool pZZ;
	bool pR;
	int pQS;
	int pQR;
	int firstCol [36];
	int secCol [36];	
};

int enterChoice ();
void viewPlayer ( fstream& );
void updatePlayer ( fstream& );
void newPlayer ( fstream& );
void deletePlayer ( fstream& );
void createFile ( fstream& );
void getPlayerInfo ( ostream&, const PlayerRecord & );
int getPIN ( const char * );

enum Choices { VIEW = 1, UPDATE, NEW, DELETE, CREATE, END };

int _tmain ( int argc, _TCHAR*  argv [] )
{
    fstream inOutPlayer ( "player.txt", ios::in | ios::out );

	if ( !inOutPlayer ) {
        cout << "Cannot open file! Closing.\n";
        return 1;
    }

	int choice;

	while ( ( choice = enterChoice () ) != END ) {

		switch ( choice ) {
		case VIEW:
			viewPlayer ( inOutPlayer );
			break;
		case UPDATE:
			updatePlayer ( inOutPlayer );
			break;
		case NEW:
			newPlayer ( inOutPlayer );
			break;
		case DELETE:
			deletePlayer ( inOutPlayer );
			break;
		case CREATE:
			createFile ( inOutPlayer );
			break;
		default:
			cerr << "Incorrect choice.\n";
			break;
		}

		inOutPlayer.clear ();
	}

	return 0;
}

	
int enterChoice () {

	cout << "\nEnter your choice" << endl
		 << "1 - View a player's card.\n"
		 << "2 - Update a player's record.\n"
		 << "3 - Add a new player.\n"
		 << "4 - Delete a player.\n"
		 << "5 - Create a new player list file.\n"
		 << "6 - End the program.\n";
	int menuChoice;
	cin >> menuChoice;
	return menuChoice;
}

void viewPlayer ( fstream &viewPlayer ) {
	
	int pINLoc = getPIN ( "Enter the player's identification number");

	cout << pINLoc << endl;

	viewPlayer.seekg ( ( pINLoc - 1 ) * sizeof ( PlayerRecord ) );

	PlayerRecord p;
	
	viewPlayer.read ( reinterpret_cast<char *> ( &p ), sizeof ( PlayerRecord ) );

	cout << p.firstName << " " << p.lastName << endl;
	if ( p.posRat[0] > 0 ) { 
		cout << "Grade ";
		if ( p.pSGrade != 0 ) {

			if ( p.pSGrade >= 28 ) {
				cout << "A&B";
			}
			if ( p.pSGrade < 28 && p.pSGrade >= 23) {
				cout << "A&C";
			}
			if ( p.pSGrade < 23 && p.pSGrade >= 18) {
				cout << "A";
			}
			if ( p.pSGrade < 18 && p.pSGrade >= 13) {
				cout << "B";
			}
			if ( p.pSGrade < 13 && p.pSGrade >= 8) {
				cout << "C";
			}
			if ( p.pSGrade < 8 && p.pSGrade > 0) {
				cout << "D";
			}
			if ( p.pSGrade != p.pRGrade ) {

				if ( p.pRGrade >= 28 ) {
					cout << "(A&B*)";
				}
				if ( p.pRGrade < 28 && p.pRGrade >= 23) {
					cout << "(A&C*)";
				}
				if ( p.pRGrade < 23 && p.pRGrade >= 18) {
					cout << "(A*)";
				}
				if ( p.pRGrade < 18 && p.pRGrade >= 13) {
					cout << "(B*)";
				}
				if ( p.pRGrade < 13 && p.pRGrade >= 8) {
					cout << "(C*)";
				}
				if ( p.pRGrade < 8 && p.pRGrade > 0) {
					cout << "(D*)";
				}
			}
		}
		else {
			if ( p.pRGrade >= 28 ) {
				cout << "A&B*";
			}
			if ( p.pRGrade < 28 && p.pRGrade >= 23) {
				cout << "A&C*";
			}
			if ( p.pRGrade < 23 && p.pRGrade >= 18) {
				cout << "A*";
			}
			if ( p.pRGrade < 18 && p.pRGrade >= 13) {
				cout << "B*";
			}
			if ( p.pRGrade < 13 && p.pRGrade >= 8) {
				cout << "C*";
			}
			if ( p.pRGrade < 8 && p.pRGrade > 0) {
				cout << "D*";
			}
		}

		cout << " Pitcher (" << p.posRat[0] << ")" << endl;
	}
	
	int j = 10;
	for ( int i = 0; i < 36; i++ ) {
		j++;
		if ( j % 10 == 7 ) {
			j += 4;
		}		
		cout << j << "- " << p.firstCol[i];
		if ( p.secCol[i] != 0 ){
			cout  << "-" << p.secCol[i];
		}
		
		cout << "\n";
	}
}

void newPlayer ( fstream &insertPlayer ) {

	int pINLoc = getPIN ( "Enter the player's identification number");

	insertPlayer.seekg ( ( pINLoc - 1 ) * sizeof ( struct PlayerRecord ) );

	PlayerRecord player;

	insertPlayer.read ( reinterpret_cast <char *> ( &player ), sizeof ( struct PlayerRecord ) );

	if ( player.pIN == 0 ) {
		
		player.pIN = pINLoc;										
		cout << "Enter player's last name and first name: ";		
		cin >> player.lastName >> player.firstName;
    
		bool valid = false;											
		while (valid == false) {
			cout << "Enter player's batting side: ";				
			cin >> player.batSide;
			switch (player.batSide) {
				case 'R': case 'L': case 'B':
					valid = true;
					break;
				default:
					break;
			}
		}
	
	
		valid = false;													
		while (valid == false) {										
			cout << "Enter player's throwing side: ";					
		    cin >> player.throwSide;
		    switch (player.throwSide) {
		        case 'R': case 'L':
			        valid = true;
					break;
		        default:
					break;
			}
		}
	
		valid = false;													 // Resets check
		char yesNo = 'N';

		cout << "Is the player a pitcher (Y/N)? ";
		cin >> yesNo;
		if ( yesNo == 'Y' ) {

			cout << "Enter player's defense rating for pitcher: ";
			cin >> player.posRat[0];

			yesNo = 'N';
			cout << "Can the pitcher start (Y/N)? ";
			cin >> yesNo;
			if (yesNo == 'Y') {

				cout << "Enter the pitcher's starting pitching rating: ";
				cin >> player.pSGrade;
				cout << "Enter the pitcher's starting pitching strength rating: ";
				cin >> player.pQS;
			
				yesNo = 'N';
				cout << "Does the pitcher have a different relief pitching rating (Y/N)? ";
				cin >> yesNo;
				if (yesNo == 'Y') {
					cout << "Enter the pitcher's relief pitching rating: ";
					cin >> player.pRGrade;
					cout << "Enter the pitcher's relief pitching strength rating: ";
					cin >> player.pQR;
				}
				else {
					player.pRGrade = player.pSGrade;
					player.pQR = player.pQS;
				}
			}
			else {
				player.pSGrade = 0;
				player.pQS = 4;
				cout << "Enter the pitcher's relief pitching rating: ";
				cin >> player.pRGrade;
				cout << "Enter the pitcher's relief pitching strength rating: ";
				cin >> player.pQR;
			}

			yesNo = 'N';
			cout << "Does the pitcher have a home run rating (Y/N)? ";
			cin >> yesNo;
			if (yesNo == 'Y') {
				cout << "Enter the pitcher's home run rating (G/H/L/M): ";
				cin >> player.pHR;
			}
			else {
				player.pHR = ' ';
			}
		
			yesNo = 'N';
			cout << "Does the pitcher have a R rating (Y/N)? ";
			cin >> yesNo;
			if (yesNo == 'Y') {
				player.pR = true;
				player.pX = false;
				player.pY = false;
				player.pK = false;
			}
			else {
				yesNo = 'N';
				cout << "Does the pitcher have a K rating (Y/N)? ";
				cin >> yesNo;
				if (yesNo == 'Y') {
					player.pK = true;
				}
				else {
					player.pK = false;
				}
				yesNo = 'N';
				cout << "Does the pitcher have an X rating (Y/N)? ";
				cin >> yesNo;
				if (yesNo == 'Y') {
					player.pX = true;
				}
				else {
					player.pX = false;
				}
				yesNo = 'N';
				cout << "Does the pitcher have a Y rating (Y/N)? ";
				cin >> yesNo;
				if (yesNo == 'Y') {
					player.pY = true;
				}
				else {
					player.pY = false;
				}
			}

			yesNo = 'N';
			cout << "Does the pitcher have a W rating (Y/N)? ";
			cin >> yesNo;
			if (yesNo == 'Y') {
				player.pW = true;
				player.pZ = false;
				player.pZZ = false;
			}
			else {
				player.pW = false;
				yesNo = 'N';
				cout << "Does the pitcher have a ZZ rating (Y/N)? ";
				cin >> yesNo;
				if (yesNo == 'Y') {
					player.pZZ = true;
					player.pZ = false;
				}
				else {
					yesNo = 'N';
					cout << "Does the pitcher have a Z rating (Y/N)? ";
					cin >> yesNo;
					if (yesNo == 'Y') {
						player.pZ = true;
					}
					else {
						player.pZ = false;
					}
				}
			}
		
			yesNo = 'N';
			cout << "Does the pitcher have a BK0 rating (Y/N)? ";
			cin >> yesNo;
			if (yesNo == 'Y') {
				player.pBK = true;
			}
			else {
				player.pBK = false;
			}
		
			yesNo = 'N';
			cout << "Does the pitcher have a HB0 rating (Y/N)? ";
			cin >> yesNo;
			if (yesNo == 'Y') {
				player.pHB = true;
			}
			else {
				player.pHB = false;
			}

			cout << "Enter the pitcher's wild pitch rating: ";
			cin >> player.pWP;

			cout << "Enter the pitcher's move to first rating: ";
			cin >> player.pMF;
		}
		else {
			player.posRat[0] = 0;
			player.pSGrade = 0;
			player.pRGrade = 0;
			player.pWP = 3;
			player.pBK = false;
			player.pHB = false;
			player.pMF = 0;
			player.pHR = 'M';
			player.pK = false;
			player.pX = false;
			player.pY = false;
			player.pW = true;
			player.pZ = false;
			player.pZZ = false;
			player.pR = true;
			player.pQS = 4;
			player.pQR = 4;
		}

		yesNo = 'N';
		cout << "Is the player a catcher (Y/N)? ";
		cin >> yesNo;
		if ( yesNo == 'Y' ) {
			cout << "Enter player's defense rating for catcher: ";
			cin >> player.posRat[1];
			cout << "Enter the catcher's throw rating: ";
			cin >> player.cThrowRat;
			cout << "Enter the catcher's passed ball rating: ";
			cin >> player.cPBRat;
		}
		else {
			player.posRat[1] = 4;
			player.cThrowRat = -5;
			player.cPBRat = 3;
		}

		yesNo = 'N';
		cout << "Is the player a firstbaseman (Y/N)? ";
		cin >> yesNo;
		if ( yesNo == 'Y' ) {
			cout << "Enter player's defense rating for first base: ";
			cin >> player.posRat[2];
		}
		else {
			player.posRat[2] = 1;
		}
	
		yesNo = 'N';
		cout << "Is the player a secondbaseman (Y/N)? ";
		cin >> yesNo;
		if ( yesNo == 'Y' ) {
			cout << "Enter player's defense rating for second base: ";
			cin >> player.posRat[3];
		}
		else {
			player.posRat[3] = 4;
		}

		yesNo = 'N';
		cout << "Is the player a thirdbaseman (Y/N)? ";
		cin >> yesNo;
		if ( yesNo == 'Y' ) {
			cout << "Enter player's defense rating for third base: ";
			cin >> player.posRat[4];
		}
		else {
			player.posRat[4] = 2;
		}
	
		yesNo = 'N';
		cout << "Is the player a shortstop (Y/N)? ";
		cin >> yesNo;
		if ( yesNo == 'Y' ) {
			cout << "Enter player's defense rating for shortstop: ";
			cin >> player.posRat[5];
		}
		else {
			player.posRat[5] = 5;
		}

		yesNo = 'N';
		cout << "Is the player an outfielder (Y/N)? ";
		cin >> yesNo;
		if ( yesNo == 'Y' ) {
			cout << "Enter player's defense rating for the outfield: ";
			cin >> player.posRat[6];
			player.posRat[7] = player.posRat[6];
			player.posRat[8] = player.posRat[6];
		}
		else {
			player.posRat[6] = 0;
			player.posRat[7] = player.posRat[6];
			player.posRat[8] = player.posRat[6];
		}

		cout << "Enter player's batting characteristic (0=SA, 1=PR, 2=PL, 3=PB): ";
		cin >> player.batChar;
			
		cout << "Enter player's left handicap and right handicap: ";
		cin >> player.lHandi >> player.rHandi;

		cout << "Enter player's steal allowance letter and rating: ";
		cin >> player.stealAllow >> player.stealRat;

		cout << "Enter player's speed and arm ratings: ";
		cin >> player.speedRat >> player.armRat;

		cout << "Enter first column: " << endl;
		int j = 10;
		for ( int i = 0; i < 36; i++ ) {
			j++;
			if ( (j % 10) == 7 ) {
				j += 4;
			}
			cout << j << ": ";
			cin >> player.firstCol[i];
		}

		yesNo = 'N';
		j = 10;
		cout << "Does the player have a second column (Y/N)? ";
		cin >> yesNo;
		if (yesNo == 'Y') {
			cout << "Enter second column: ";
			for (int i = 0; i < 36; i++) {
				j++;
				if ( (j % 10) == 7 ) {
					j += 4;
				}				
				cout << j << ": ";
				cin >> player.secCol[i];
			}
		}
		
		int z = sizeof ( struct PlayerRecord );
		cout << "\n" << z;

		insertPlayer.seekp ( (player.pIN - 1 ) * sizeof ( struct PlayerRecord ) );
		insertPlayer.write ( reinterpret_cast <const char *> ( &player ) ,
		     				 sizeof ( struct PlayerRecord ) );

	}
	else {
		cerr << "PIN number " << pINLoc << " already contains information." << endl;
	}
}

void createFile ( fstream &newFile ) {

	PlayerRecord b = { 0, ' ', ' ', {""}, {""}, {0}, 0, 0, 0, 'N', 0, 0, 0, 0, 0, 0, 0, 0, false,
								 false, 0, ' ', false, false, false, false, false, false, false, 0,
								 0, {0}, {0} };
	
	newFile.seekp ( ( b.pIN ) * sizeof ( struct PlayerRecord ) );
		
	for ( int i = 0; i < 698; i++ ) {
		newFile.write ( reinterpret_cast <const char *> ( &b ) ,
		     			sizeof ( struct PlayerRecord ) );
		
	}
}

int getPIN ( const char *prompt ) {

	int pIN;

	do {
		cout << prompt << " (1 - 698): ";
		cin >> pIN;
	} while (pIN < 1 || pIN > 698);

	return pIN;
}

void updatePlayer ( fstream &updatePlayer ) {}
void deletePlayer ( fstream &deletePlayer ) {}

Any advice/hints would be appreciated. I'm not sure if this code snippet is too long, so if I need to pare it down, please let me know and I will do so.

Edited 5 Years Ago by grebote: n/a

I copied your code down and compiled it; it seems to work fine for me. I added 3 players, and I can run the code and display all three just fine. I stopped the program and ran it again, and all of my data was still intact.

I did have to make some changes to get your code to compile. It looks like a windows console app; but it was attempting to include "stdafx.h", as well as it had the "_tmain" entry point, and "_TCHAR* as the type for "argv"; I removed all of these, replacing them with "main" and "char *", and compiled it as a straight C++ console app.

I then created a new Win32 project, and in the wizard stated I wanted it to be a console app, and was able to get your code to compile straight from your submission.

In both cases, the program ran fine. I copied the data file from the first project to the second, and was able to successfully browse the data.

Structurally, the code appears to be fine. Couple of notes:

1) the program just quits if it can't load "players.txt". You could just create a new, empty file in that case, instead of making me do it ;)
2) I'm a baseball fan, but not a huge baseball *stats* fan, so, in the code when you ask when a player is a pitcher, catcher, etc. - are these mutually exclusive, or can a player have stats in more than one category? If the former, once the user says the player is a "catcher", it shouldn't ask anymore position questions.

Of course, those are just nits, and don't have anything to do with the issue you're having.

How many players did you add before things went haywire?

Thanks for checking out my code. I made the changes that you suggested, and I tried running it through a different complier (Dev-C++ instead of Visual C++ 2010). Unfortunately, I am getting the same errors as before, except this time when I tried to output the array, I got a whole bunch of strange numbers, including negatives. The output goes haywire after I add the first player to the file.

As for your suggestions, I'll work on creating a file if there isn't one present. I'm not quite sure how to do that yet since I haven't run across it, but it would be a good thing to include. Also, the positions are not mutually exclusive, since many players are capable of playing multiple positions, including a few position players here and there that can pitch.

Anyway, thanks again. I'm glad its working on your system, I just wish I could get it to work on mine!

I ran the code in Visual Studio 2010 (full version, not Express), and I'm running Win 7/64-bit.

Here are the steps I went through with my setup:

1) In VS2010, from the "File" menu, select "New | Project"
2) In the box, click on "Visual C++", and in the right-hand side, select "Win32 Project".
3) Type a name for the project and press OK.
4) In the wizard, press "Next >".
5) Change the type to "Console application". Press "Finish".
6) Overlay the code in the main C++ code file (whatever you named the project), with the code from your post.

I just did it again (to write the above steps) and it works fine. I've attached my "players.txt" file - put it where your program can get it and see if you can read it with your version of the code.

So...this is weird, I followed your directions explicitly, then compiled. I can view the ones that you created no problem...but then I tried to create my own, and I got the same issue when I tried to view entry. I'm on the same system as you, Win 7/64-bit, but I do have the express version of Visual C++. If I give you some data, would you mind inserting it into the file and seeing if you can view it?

70
BOYER KEN
R
R
N
N
N
N
Y
5
N
N
2
5 -4
D 21
16 35
And for the first column (no second column):
4 25 14 30 10 28 30 5 33 13 8 27 9 26 5 31 9 12 24 14 29 7 14 13 8 27 20 32 8 13 39 26 31 22 35 1

I ran the program with your data, and lo and behold, I started to get the same results! After looking at it for some time, and monkeying around with the structure, and other things, I happened to look at the top of the program:

fstream inOutPlayer ( "player.txt", ios::in | ios::out );

You're reading and writing data via structs (i.e., binary mode)! So, try this:

fstream inOutPlayer ( "player.txt", ios::in | ios::out | ios::binary );

Your code should work much better.

I noticed you have a lot of variables in one structure, I usually try to nest some structures like this:

struct CategoryOne{
int a;
int b;
std::string s;
};
struct CategoryTwo{
bool tf;
double d;
};
struct AllMyData{
CategoryOne catOne;
CategoryTwo catTwo;
};

I am only posting this because I think it may make all those variables easier to manage.

Yes, that change worked! Thanks so much, Mike. I had fiddled with opening in binary mode last night but still couldn't get it to work, so I'm glad that it was such a simple fix.

That's a good idea on nesting the data into multiple structures, I'll try to work that in to the program.

Thanks again, marking the thread as "solved."

This question has already been answered. Start a new discussion instead.