Hi, I am having a very hard time understanding what I am doing wrong here.

I am trying to read from a file into a struct array, however it stops working properly after a short while.

my data in the file is in the following format:

Last, First Name
ID Number
4 grades recieved
and so on...

specific example

Doe, John
123-4567
7 10 6 7
Doe, Jane
098-7654
7 7 7 6

here is my code so far...

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>	// do i need last 3?
#include <stdlib.h>
#include <ctype.h>

using namespace std;

const int MAX_NAME_LENGTH = 16;		//actual is 16
const int ID_NUMBER_LENGTH = 9;		//actual is 9

struct st_Student_Info					//structure decloration
{
	char name[MAX_NAME_LENGTH];		//name of student    last, first
	char idNumber[ID_NUMBER_LENGTH];	//student ID number
	int grade1;							//grades for student
	int grade2;
	int grade3;
	int grade4;
};

typedef struct st_Student_Info StudentInfo;

const int MAX_DB_SIZE = 31;				//actual size is 31

StudentInfo currDB[MAX_DB_SIZE];


//begin function prototypes
int ReadDB(const int DBSize);

int main()
{
	int nStudents = ReadDB(MAX_DB_SIZE);
	
	cout << nStudents << endl;

	return 0;
}

int ReadDB(const int DBSize)
{
	ifstream fIn;
	fIn.open("student.dat"); //input
	if (!fIn)
	{
		cout << "Can't open txt file." << endl;
		return -99;
	}

	int i = 0;		//counter
	for(i = 0; i< DBSize; i++)
	{
		fIn.getline (currDB[i].name, MAX_NAME_LENGTH);
		fIn.getline (currDB[i].idNumber, ID_NUMBER_LENGTH);
		fIn >> currDB[i].grade1 >> currDB[i].grade2 >> currDB[i].grade3 >> currDB[i].grade4;

		
		cout << "n " << currDB[i].name << endl;
		cout << "# " << currDB[i].idNumber << endl;
		cout << "1 " << currDB[i].grade1 << endl;
		cout << "2 " << currDB[i].grade2 << endl;
		cout << "3 " << currDB[i].grade3 << endl;
		cout << "4 " << currDB[i].grade4 << endl;
	}
	fIn.close();
	return i;
}

im pretty sure my errors are caused by the .getline and >> but i cant tell.

any help is appreciated!

Recommended Answers

All 5 Replies

I think you messed it up a bit, for example reading a database should be void. I didn't separate my solution, excuse me for that. The size-1 in the loop is a mistery for me, it worked only that way, otherwise there were a "bonus" record, I think it depends on the input.

#include <iostream>
#include <vector>
#include <fstream>

using namespace std;

struct Student
{
    string name;
    string ID;
    int grade1,grade2,grade3,grade4;
};

int main ()
{
    vector<Student> database;
    ifstream fileread("student.dat");
    while(!fileread.eof())
    {
        Student t[1];
        string temp1,temp2;
        int temp3,temp4,temp5,temp6;
        fileread >> temp1 >> temp2 >> temp3 >> temp4 >> temp5 >> temp6;
        t[0].name=temp1;
        t[0].ID=temp2;
        t[0].grade1=temp3;
        t[0].grade2=temp4;
        t[0].grade3=temp5;
        t[0].grade4=temp6;
        database.push_back(t[0]);
    }
    int size = database.size();
    for (int i=0;i<size-1;i++)
    {
        cout << "N " << database[i].name << endl;
        cout << "# " << database[i].ID << endl;
        cout << "1 " << database[i].grade1 << endl;
        cout << "2 " << database[i].grade2 << endl;
        cout << "3 " << database[i].grade3 << endl;
        cout << "4 " << database[i].grade4 << endl;
        cout << "\n";
    }
    fileread.close();
}

If you have any questions, or you need more help, feel free to PM me. (:

Well, Mr. blackrainbow, your solution isn't much better than the original. This assumes no white space in either the name or ID rows of the file.

Student t;
    while( fileread >> t.name >> t.ID >> t.grade1 >> t.grade2 >> t.grade3 >> t.grade4 )
    {
        database.push_back(t);
    }

If it can contain white space then do it like this

Student t;
while( getline(fileread, t.name) )
{
   getline(fileread.t.id);
   fileread >> t.grade1 >> t.grade2 >> t.grade3 >> t.grade4;
   fileread.ignore(); // remove '\n' at end of line
   database.push_back(t);
}

I tought the only problem was the fatal error.

Update:

I don't really get what you are talking about by the way. My input was like

XY 54545 4 5 6 7
ZX 54545 4 4 4 4
YY 32323 3 4 5 6

And it worked, no need to remove \n.

There is a '\n' at the end of every line. getline() won't work right if you don't remove it from the previus line. And for strings >> won't work if there is a chance that there might be spaces in the name and/or ID fields. such as "John <space> Doe"

I said your code snippet isn't right because eof() does't work that way and because its too overly complicated and awkward. There is no need for the array of Student structures with only one element nor is there any need for all those temp variables. Simplicity is the key to good programming. Don't try to impress anyone with your c++ skills, it only makes you look bad.

Hm, you are right. I didn't want to impress anyone by the way, I always think a bit complicated. :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.