Adding data to a vector from file while still using the original set/g

How to add data to a vector filled with class objects from a file?

Page 1 of 1

9 Replies - 2468 Views - Last Post: 14 October 2008 - 05:38 AM Rate Topic: -----

#1 hk416  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 19
  • Joined: 11-October 08

Adding data to a vector from file while still using the original set/g

Posted 11 October 2008 - 07:30 PM

I'm new to hi-level programming in general and to C++, and as such I've run into a problem while working on an assignment.
As you can see, the comments are not in english as is some of the code. Nor is the code posted anywhere near complete, but i don't think it is necessary to post the enterie thing just for this problem (Unlss otherwise specified by you guys ofcource). I really should start to write my code in english as it would probably be alot easier to work with. If there are any questions regarding the language, variable names and such, post away!

The basic gist of the program is that the user can input data about a person, here; name and a number. The name (varible "navn") gets sent to the "nyStudent" -function, inserted into the object "nyStudent" of type "Student", then the object gets pushed into the vector "studenter". Now the number (variable "studentnummer") can be added to the specified name "navn" if found in the vector.

Now for the problem at hand; how do i achive the exact same thing, but not from user input in the program but rather from a file instead?. In the program the user has the option to save all of the data into a CSV file. Then at a later time, the user can opt to load the data back into the "studenter" -vector to continue working on it.

Now i've figured out how to read and split up the data. My problem is getting that data into the "studenter" -vector again in the correct way, so that when i run my code snippet for getting and displaying the variables, it comes out correct.

Any helpful advice on this issue would be very much appreciated!

Thanks in advance
William


//The following code belongs to the class "Student":.......

Student::Student()									//Default konstruktør; Implementsjon
		:navn(""),
		 karakter("")
{}

Student::Student(const string &studNavn)			//Konstruktør 1; Implementsjon						
		:navn(studNavn),
		 karakter("")
{}
	
//SET-FUNKSJONER
void Student::setNavn(const string &_Navn){
	navn = _Navn;
}	

void Student::setStudentnummer(const string &_Studentnr){
	studentnummer = _Studentnr;
}

//GET-FUNKSJONER
const string &Student::getNavn() const{
	return navn;
}

const string &Student::getStudentnummer() const{
	return studentnummer;
}

//The following code belongs to the class "Studentadmin":....
//It has a private vector "vector<Student> studenter;" wich contains user inputted data or data from file.

void Studentadmin::nyStudent(const string &navn){								//tar i mot navn fra bruker som argument
	Student nyStudent(navn);													//plasserer navn inn i objektet "nyStudent" av typen "Student"
	studenter.push_back(nyStudent);												//plasserer objektet "nyStudent" inn i vektoren "studenter"
}

//SET-FUNKSJONER
bool Studentadmin::setStudentnr(const string &navn, const string &studnr)
{
	Student student(navn);																		//oppretter et objekt "student" av typen "Student" og putter "navn" inn i objektet
	vector<Student>::iterator studenten = find(studenter.begin(), studenter.end(), student);	//bruker en iterator til vektoren og leter i fra begynnelse til slutt etter den gitte studenten
		if (studenten < studenter.end()){														//hvis studenten befinner seg i vektoren
			studenten->setStudentnummer(studnr);												//setter inn "studnr" for studenten i setStudentnummer-funksjonen (studenten er her da navnet)
			return true;																		//returnerer true hvis OK
		}else
			return false;																		//ellers returnerer false
}		

//GET-FUNKSJONER
string Studentadmin::getStudentnr(const string &navn) const		
{		
	Student student(navn);																				//oppretter et objekt "student" av typen "Student" og putter "navn" inn i objektet
	vector<Student>::const_iterator studenten = find(studenter.begin(), studenter.end(), student);		//bruker en iterator til vektoren og leter i fra begynnelse til slutt etter den gitte studenten
		if (studenten < studenter.end()){																//hvis studenten befinner seg i vektoren
			return studenten->getStudentnummer();														//returnerer studentnummeret
		}else
			return 0;																					//ellers returnerer 0
}		

const Student *Studentadmin::getStudent(int indeks) const					//henter ut innholdet for en gitt indeks i vektoren
{
	if (indeks >= 0 && indeks < studenter.size()){							//hvis indeksen er innenfor antall elementer
		return &studenter[indeks];											//returnerer innholdet på gitt indeks
	}else{
		return 0;															//ellers returneres 0
	}
}

void Studentadmin::delOppData(string &inndata)
{
//This function when called, gets passed a filepath from the user as argument. Based on the specified filepath, it opens the CSV type file, reads the contents, splits up the data by delimitersign and then data is supposed to be passed to the "studenter" -vector so the user can modify or add data.
}

//Here comes the 'main' part of the program:...
int main(){ 
	Studentadmin studentdata;										//oppretter et objekt, "studentdata", av typen "Studentadmin"	
	{	
		visOverskrift();											//viser programmets overskrift
		valg menyvalg = (valg) visHovedmeny();						//viser programmets hovedmeny
		while (menyvalg != avslutt){								//fortsetter så lenge brukeren ikke velger avslutt
			visMenyvalg(menyvalg, studentdata);						//kaller på menytreet, sender inn menyvalg og objekt
			menyvalg = (valg) visHovedmeny();						//setter variabelen "menyvalg" lik variabelen "valg" fra funksjonen visHovedmeny();
		}
	}	
	return 0; 
}

//This function contains most of the clientprogram:.....

int visMenyvalg(valg menyvalg, Studentadmin &data) {

//Here is a submenu where the user can choose to open a CSV file of previous stored data so he can modify the data as he sees fit. The user selects a filepath wich is passed to the "delOppData" -function.

//User input, all user input is of type string:....
do{
	cout << " Navn: ";
	getline(cin, navn, '\n');								//navn fra bruker
	cout << endl;
	}while(navn.empty());								//gjenta hvis bruker ikke skriver inn noe

do {	
	cout << " Studentnummer: ";
	getline(cin, studentnummer, '\n');						//studentnummer fra bruker
	cout << endl;
	}while(studentnummer.empty());								//gjenta hvis bruker ikke skriver inn noe


//The user input "navn" and "studentnummer" gets passed to their respective set-functions.
data.nyStudent(navn);									//setter studentens navn
data.setStudentnr(navn, studentnummer);					//setter studentens studentnummer	

//The following code is used to extract data from the vector and view it:...
for (int indeks = 0; indeks < data.getAntStudenter(); indeks++)		//lister opp og viser tilgjengelige studenter
{
	const Student *studenten = data.getStudent(indeks);				//går igjennom indeksen til hvert element
	cout << " <" << (indeks + 1) << ">";							//indeksnummer
	cout << " :: " << studenten->getStudentnummer() << " :: ";		//studentnummer
	cout << studenten->getNavn() << endl;							//navn
}

//here comes a submenu for the user to specify a file to wich the data can be stored for later use and the ability to save the data to file


return 0;
}
End of program.....




Is This A Good Question/Topic? 0
  • +

Replies To: Adding data to a vector from file while still using the original set/g

#2 Martyr2  Icon User is offline

  • Programming Theoretician
  • member icon

Reputation: 4321
  • View blog
  • Posts: 12,106
  • Joined: 18-April 07

Re: Adding data to a vector from file while still using the original set/g

Posted 11 October 2008 - 08:53 PM

Well right where you have the code in visMenyvalg...

//User input, all user input is of type string:....
do{
    cout << " Navn: ";
    getline(cin, navn, '\n');       //navn fra bruker
    cout << endl;
}while(navn.empty());           //gjenta hvis bruker ikke skriver inn noe




You will be replacing it with objects out of <fstream>. You will create a ifstream object and give it the csv filename as you create it. This will open the file from which you can use read functions like getline or the << operator to read in data such as the Navn and Studentnummer, create the student object with that info, then push it on the vector.

Just remember to keep reading until you hit EOF and make sure you check to see if the file is open before attempting to read from it. Then at the end make sure you close the ifstream using its close() method.

Not too different from asking for screen input. Hope that helps you out.

"At DIC we be Navn and Studentnummer collecting code ninjas....we be kølig!" :snap:
Was This Post Helpful? 1
  • +
  • -

#3 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 280
  • View blog
  • Posts: 1,787
  • Joined: 20-September 08

Re: Adding data to a vector from file while still using the original set/g

Posted 11 October 2008 - 09:17 PM

Here is some code that writes to file and reads back from file ... you can cherry pick what you like.

Shalom,

David


// demoAddressBook.cpp

#include <string>
#include <fstream>
#include <iostream>

using namespace std;

class Entry
{
   friend istream&operator>>(istream&, Entry&);
   friend ostream&operator<<(ostream&, Entry&);

   public:

	  // default constructor
	  Entry(){}

	  // constructors
	  Entry(string N, string A1, string A2, string P)
	  {
		  Person=N; Add1=A1; Add2=A2; Phone=P;
	  }

	  void setPerson(string temp){Person=temp;}
	  void setAdd1(string temp){Add1=temp;}
	  void setAdd2(string temp){Add2=temp;}
	  void setPhone(string temp){Phone=temp;}

	  // accessors
	  string getPerson(){return(Person);}
	  string getAdd1(){return(Add1);}
	  string getAdd2(){return(Add2);}
	  string getPhone(){return(Phone);}

   private:

	  string   Person,
			   Add1,
			   Add2,
			   Phone;
};

/* -----------------------------------------------------
   FRIEND FUNCTION TO OVERLOAD THE >> OPERATOR FOR INPUT
   ----------------------------------------------------- */
istream &operator>>(istream &input, Entry &e)
{
   string temp[5];
   for(int i=0; i<5; i++) getline(input, temp[i], '\n');
   Entry e_temp(temp[0],temp[1],temp[2],temp[3]);
   e=e_temp;
   return(input);
}
/* ------------------------------------------------------
   FRIEND FUNCTION TO OVERLOAD THE << OPERATOR FOR OUTPUT
   ------------------------------------------------------ */
ostream&operator<<(ostream &output, Entry &e)
{
   output << e.getPerson()<<endl
		  << e.getAdd1()<<endl
		  << e.getAdd2()<<endl
		  << e.getPhone()<<endl;
   return(output);
}


// prototypes of functions used in 'main'
void createBook(Entry[], int&); // start new book
void printBook(Entry[], int); // print the current book to screen

void readBook(char[], Entry[], int &); // read book from file
void writeBook(char[], Entry[], int); // write the current book to file



// main begins ... first set Global const MAX
const char line[]="-----------------------------------";
const int MAX=10;

int main()
{
	 
   Entry Book[MAX]; // construct an array of 'entries' of size MAX

   int last;
   createBook(Book, last); // construct Book

   cout << "\nHere is the 'book' you just created ...\n";
   cout << line << endl;
   printBook(Book, last);  // show book on screen
   writeBook("MyBBook.dat", Book, last); // write Book to file MyBBook.dat

   cout << "\nThe 'last' record is " << last << "\n\n";
   system("pause");

   readBook("MyBBook.dat", Book, last); // read Book from file MyBBook.dat
   cout << "\nHere is the 'book'  read  from file ...\n";
   cout << line << endl;
   printBook(Book, last);

   cout << "The 'last' record is " << last << "\n\n";

   system("pause");
   return 0;
}


// definitions of functions used in 'main'
string takeIn(string message)
{
   cout<<message<<": ";
   string inStr;
   getline(cin, inStr, '\n');
   return(inStr);
}

void createBook(Entry b[], int &last)
{
   int i=0; bool more=true;
   while( (i<MAX) && more )
   {
	  b[i].setPerson(takeIn("Enter name			"));
	  b[i].setAdd1  (takeIn("Enter address 1st line"));
	  b[i].setAdd2  (takeIn("Enter address 2nd line"));
	  b[i].setPhone (takeIn("Enter phone		   "));

		if("n"==(takeIn("More y/n ?			"))) more=false;

	  i++;
   }
   last=i;
}

void printBook(Entry b[], int last)
{
   for(int i=0; i<last; i++ ) cout << b[i] << endl;
}

void writeBook(char f[], Entry b[], int last) // write the current book to file
{
   // 5 lines of data to write for each 'entry' (includes 5th blank line)
   ofstream OUTFILE( f );
   for(int i=0; i<last; i++) OUTFILE << b[i] << endl;
   OUTFILE.close();
}

void readBook(char f[] , Entry b[], int & last)
{
   ifstream INFILE( f );
   int i=0;
   while( (INFILE >> b[i]) && (i<last) ) { i++; }
   INFILE.close();
} 

Was This Post Helpful? 1
  • +
  • -

#4 hk416  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 19
  • Joined: 11-October 08

Re: Adding data to a vector from file while still using the original set/g

Posted 12 October 2008 - 05:52 AM

Hmm... this is how far i have gotten:

The "lesFil" -function located in the class "Filstyring", when passed a user-defined filepath, opens the storagefile for reading. The contents of the file is passed to the function "delOppData", located in the class "Studentadmin".

The "delOppData" -function now looks like this. It splits up inbound data into three seperate substrings based on
their location within the read line. The first substring corresponds to the "studentnummer" parameter, the second
substring is the "navn" parameter and then there is a third parameter also. It is at this point where
i'm not sure what to do. Should the code for pushing back the parameters look something like the exsisting code?:

"Student nyStudent(navn);
studenter.push_back(nyStudent);"

Martyr2 wrote something about creating new student objects with the read data read from file?

Thanks in advance
William

//The "lesFil" -function located in the class "Filstyring", when passed 
a user-defined filepath, opens the storagefile for reading. 
The contents of the file is passed to the function "delOppData" 
located in the class "Studentadmin". 

string Filstyring::lesFil(const string &filbanefagfil)										//leser studentdata fra den aktuelle lagringsfilen
{//start funksjon les data fra fagfil
	Studentadmin inndata;																	//oppretter et objekt "inndata" av typen "Studentadmin"
	Studentadmin *Peker;																	//oppretter en peker til klassen Studentadmin
	Peker = &inndata;																		//setter Peker lik referansen til inndata, dvs. at man kan nå alle medlemsfunksjonene til klassen Studentadmin via Peker
	
	ifstream innfrafagfil;																	//Filstrøm inn	
	innfrafagfil.open(filbanefagfil.c_str(), ios::in); 										//Åpner innfilen
	if(innfrafagfil.fail()){
		cout << " Det har oppst" << (char)134 << "tt en feil ved " << (char)134 << "pning av fila: " << filbanefagfil << "!" << endl;		//beskjed til bruker
		cout << " Avslutter... " << endl;
		exit(0);																			//lukker programmet
	}
	if(innfrafagfil.is_open()){																//hvis åpen
		while(getline(innfrafagfil, listoppfagdata, '\n') && !innfrafagfil.eof()){			//leser data fra fil og sjekker mot end of file	   
			Peker->delOppData(listoppfagdata);												//sender inndata til funksjonen "delOppData" i klassen Studentadmin via en peker
			//cout << " " << listoppfagdata << endl;										//viser innholdet
		}
		innfrafagfil.close();																//Lukker fil
		cout << " Data lastet! " << endl;													//beskjed om at dataene er lastet
	}									
	return listoppfagdata;																	//returnerer 0
}//slutt funksjon les data fra fagfil

//The "delOppData" -function now looks like this. It splits 
up inbound data into three seperate substrings based on 
their location within the read line. 
The first substring corresponds to the "studentnummer" parameter,
 the second substring is the "navn" parameter and then there is a 
third parameter also. It is at this point where 
i'm not sure what to do. Should the code for pushing back 
the parameters look something like the exsisting code?:
"Student nyStudent(navn);						
studenter.push_back(nyStudent);"	

void Studentadmin::delOppData(string &inndata)
{
													
	istringstream data(inndata);											//laster inndata fra fil inn i en stringstream slik at getline kan brukes
	while(getline(data, inndata)){											//mens lesing fra datastrøm linje for linje
		linjebitnr = 0;														//nullstiller linjetelleren
		linjenr++;															//teller opp antall leste linjer
		//cout << " Student #: " << linjenr << ":" << endl;
		istringstream studinfo(inndata);									//laster inndata fra fil inn i en stringstream slik at getline kan brukes
		while(getline(studinfo, linjebit, ';')){							//mens lesing fra datastrøm og oppdeling av data til elementer begranset av semikolon
			linjebitnr++;													//øker lest linjenummer
			//cout << " Data #" << linjebitnr << ": " << linjebit << endl;
if(linjebitnr == 1){										//hvis det er den første biten av innstringen
	Student nyStudent(linjebit);				//studentnummer
	studenter.push_back(nyStudent);							
}
if(linjebitnr == 2){										//hvis det er den andre biten av innstringen
	Student nyStudent(linjebit);				//navn		
	studenter.push_back(nyStudent);						
}
if(linjebitnr == 3){										//hvis det er den tredje biten av innstringen
	Student nyStudent(linjebit);				//third parameter		
	studenter.push_back(nyStudent);						
}

}
}
}



This post has been edited by hk416: 12 October 2008 - 02:43 PM

Was This Post Helpful? 0
  • +
  • -

#5 Martyr2  Icon User is offline

  • Programming Theoretician
  • member icon

Reputation: 4321
  • View blog
  • Posts: 12,106
  • Joined: 18-April 07

Re: Adding data to a vector from file while still using the original set/g

Posted 12 October 2008 - 04:28 PM

Yes, read in the data from the file, pass that read in fields into the constructor of your student (the students name and then set their number) and then push them onto the vector.

Peusocode...

open file
	  if successful
			While file != EOF
				  Read in student's name
				  Read in student's number
				  Create student object using students name
				  Set students number
				  vector.push_back(student object)
			End while
			Close file
	  Else
			Error, unable to open file
End program



So basically you will loop through the file reading in names and numbers, creating students that you will push onto your vector. At the end your vector will be loaded with all the students from the file.

Hope you understand the idea. :)
Was This Post Helpful? 0
  • +
  • -

#6 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 280
  • View blog
  • Posts: 1,787
  • Joined: 20-September 08

Re: Adding data to a vector from file while still using the original set/g

Posted 12 October 2008 - 09:20 PM

See next post ... (Had to take this one down for major repair) :rolleyes:

This post has been edited by David W: 13 October 2008 - 12:09 AM

Was This Post Helpful? 0
  • +
  • -

#7 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 280
  • View blog
  • Posts: 1,787
  • Joined: 20-September 08

Re: Adding data to a vector from file while still using the original set/g

Posted 12 October 2008 - 11:44 PM

This may be more like what you are looking for ...

Doesn't use push_back ... which can slow you down if you are processing HUGH vectors of objects ... B)

 // demoAddressBook2.cpp 
// using vectors to hold objects ...
#include <vector>
#include <string>
#include <fstream>
#include <iostream>

using namespace std;

class Entry
{
   friend istream&operator>>(istream&, Entry&);
   friend ostream&operator<<(ostream&, Entry&);

   public:

	  // default constructor
	  Entry(){}

	  // constructors
	  Entry(string N, string A1, string A2, string P)
	  {
		  Person=N; Add1=A1; Add2=A2; Phone=P;
	  }

	  void setPerson(string temp){Person=temp;}
	  void setAdd1(string temp){Add1=temp;}
	  void setAdd2(string temp){Add2=temp;}
	  void setPhone(string temp){Phone=temp;}

	  // accessors
	  string getPerson(){return(Person);}
	  string getAdd1(){return(Add1);}
	  string getAdd2(){return(Add2);}
	  string getPhone(){return(Phone);}

   private:

	  string   Person,
			   Add1,
			   Add2,
			   Phone;
};

/* -----------------------------------------------------
   FRIEND FUNCTION TO OVERLOAD THE >> OPERATOR FOR INPUT
   ----------------------------------------------------- */
istream &operator>>(istream &input, Entry &e)
{
   string temp[5];
   for(int i=0; i<5; i++) getline(input, temp[i], '\n');
   Entry e_temp(temp[0],temp[1],temp[2],temp[3]);
   e=e_temp;
   return(input);
}
/* ------------------------------------------------------
   FRIEND FUNCTION TO OVERLOAD THE << OPERATOR FOR OUTPUT
   ------------------------------------------------------ */
ostream&operator<<(ostream &output, Entry &e)
{
   output << e.getPerson()<<endl
		  << e.getAdd1()<<endl
		  << e.getAdd2()<<endl
		  << e.getPhone()<<endl;
   return(output);
}


// prototypes of functions used in 'main'
int createBook( vector< Entry >& ); // start new book
void printBook(vector< Entry >&, int); // print the current book to screen

int readBook(char[], vector< Entry >& ); // read book from file
int writeBook(char[], vector< Entry >&, int); // write the current book to file



// main begins ... first set Global const MAX
const char line[]="-----------------------------------";
const int MAX=3;

int main()
{
   vector< Entry > Book( MAX ); // construct a vector to hold MAX 'ENTRY' objects
   int last = createBook( Book ); // take in data from keybord to make NEW Book
   if (last == MAX )
   {
	  cout << "\nMemory has MAXed out ...\n"
		   << "See Programmer to see if an increase is possible ...\n"
		   << "Press 'Enter' to continue ... ";
	  cin.sync();
	  cin.get();
   }
   
   cout << "\nHere is the 'book' you just created ...\n";
   cout << line << endl;
   printBook(Book, last);  // show book on screen
   int condition = writeBook("myBook.dat", Book, last); 
   if ( condition == -1 )
   {
	  cout << "\nERROR writing file ... Press 'Enter' to exit ... \n";
	  cin.sync();
	  cin.get();
	  return -1; // exit program now ...
   }
   // ok ... we reached here so we had a successful write to file then :)
   cout << "\nThe 'Entry' count now is " << last 
		<< " ... Press 'Enter' to continue ... \n\n";
   cin.sync();
   cin.get();

   last = readBook("myBook.dat", Book ); // read Book from file MyBBook.dat
   cout << "\nHere is the 'book'  read  from file ...\n";
   if ( last == -1 )
   {
	  cout << "\nERROR reading file ... Press 'Enter' to exit ... \n";
	  cin.sync();
	  cin.get();
	  return -1; // exit program now ...
   }
   else if ( last == MAX )
   {
	  printBook(Book, last);  
	  cout << "\nFile may exceed MAX capacity of program ...\n"
		   << "See Programmer to see if an increase is possible ...\n";
	  cin.sync();
	  cin.get();
	  return -2; // exit program now ...
   }
   else
   {
	  cout << line << endl;
	  printBook(Book, last);
	  cout << "\nThe 'Entry' count now is " << last << "\n\n";		
   }
	  
   system("pause");
   return 0;
}


// definitions of functions used in 'main'
string takeIn(string message)
{
   cout<<message<<": ";
   string inStr;
   getline(cin, inStr, '\n');
   return(inStr);
}

// Here is a little modification that might work for you ...
int createBook( vector< Entry > & b )
{
   int i=0; bool more=true;
   Entry tmp;
   while( (i<MAX) && more )
   {
	  tmp.setPerson(takeIn("Enter name			"));
	  tmp.setAdd1  (takeIn("Enter address 1st line"));
	  tmp.setAdd2  (takeIn("Enter address 2nd line"));
	  tmp.setPhone (takeIn("Enter phone		   "));
	  b[i] = tmp;

		if("n"==(takeIn("More y/n ?			"))) more=false;

	  i++;
   }
   return i;
}

void printBook( vector< Entry > & b, int last)
{
   for(int i=0; i<last; i++ ) cout << b[i] << endl;
}

int writeBook(char f[], vector< Entry > &b, int last) // write the current book to file
{
   // WRITE 5 lines of data to write for each 'entry' (includes 5th blank line)
   
   ofstream OUTFILE( f );
   if ( !OUTFILE.is_open() ) return -1; // report error condition ...
   
   // else ...
   for(int i=0; i<last; i++) OUTFILE << b[i] << endl;
   OUTFILE.close();
   return 0; // report success ...
}

// You could declare your own temp record here and fill it from file

// Since my obj had just 4 strings as private data
// each written to its own line in the text file
// (plus a blank separator line)

// Read back like this ...
int readBook(char f[] , vector < Entry > & b )
{
   ifstream INFILE( f );
   if ( !INFILE.is_open() ) return -1; // report error condition ...

   // else ...
   int i=0;
   while( (i<MAX) && (INFILE >> b[i]) ) { i++; }
   INFILE.close();
   if (i < MAX ) return i; // success ...
   return MAX; // possible need to increase MAX in program
}

This post has been edited by David W: 13 October 2008 - 12:55 AM

Was This Post Helpful? 0
  • +
  • -

#8 hk416  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 19
  • Joined: 11-October 08

Re: Adding data to a vector from file while still using the original set/g

Posted 13 October 2008 - 02:54 AM

View PostMartyr2, on 12 Oct, 2008 - 04:28 PM, said:

Yes, read in the data from the file, pass that read in fields into the constructor of your student (the students name and then set their number) and then push them onto the vector.

Peusocode...

open file
	  if successful
			While file != EOF
				  Read in student's name
				  Read in student's number
				  Create student object using students name
				  Set students number
				  vector.push_back(student object)
			End while
			Close file
	  Else
			Error, unable to open file
End program



So basically you will loop through the file reading in names and numbers, creating students that you will push onto your vector. At the end your vector will be loaded with all the students from the file.

Hope you understand the idea. :)

Hmm, I think i know what you are getting at but I'm unsure about the actual code to get i done. I've created a temporary storagevector for each of the read parameters until i know how to get them into the "studenter" -vector.
vector<string> innStudnr;			//contains the "studentnummer" -parameter
vector<string> inNavn;				//contains the "navn" -parameter
vector<string> innKarakter;			//contains the third parameter


So what you are saying is that i should use the exsisting set-methods to pass the parameters back into the "studenter" -vector?
//Exsisting set-method for setting new students names 
void Studentadmin::nyStudent(const string &navn){								//tar i mot navn fra bruker som argument
	Student nyStudent(navn);													//plasserer navn inn i objektet "nyStudent" av typen "Student"
	studenter.push_back(nyStudent);												//plasserer objektet "nyStudent" inn i vektoren "studenter"
}
//Exisiting set-method for setting a students number 
bool Studentadmin::setStudentnr(const string &navn, const string &studnr)
{
	Student student(navn);																		//oppretter et objekt "student" av typen "Student" og putter "navn" inn i objektet
	vector<Student>::iterator studenten = find(studenter.begin(), studenter.end(), student);	//bruker en iterator til vektoren og leter i fra begynnelse til slutt etter den gitte studenten
		if (studenten < studenter.end()){														//hvis studenten befinner seg i vektoren
			studenten->setStudentnummer(studnr);												//setter inn "studnr" for studenten i setStudentnummer-funksjonen (studenten er her da navnet)
			return true;																		//returnerer true hvis OK
		}else
			return false;																		//ellers returnerer false
}


The code i have for passing the parameters looks like this:
void Studentadmin::lastDatafraLagringsVektor(){	
for(index = 0; index < inNavn.size(); index++){
	nyStudent(inNavn.at(index));
		
}

for(index0 = 0; index0 < innStudnr.size(); index0++){
	for(index = 0; index < inNavn.size(); index++){
		setStudentnr(inNavn.at(index), innStudnr.at(index0));
			
	}
}
}



Thanks in advance
William
Was This Post Helpful? 0
  • +
  • -

#9 hk416  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 19
  • Joined: 11-October 08

Re: Adding data to a vector from file while still using the original set/g

Posted 13 October 2008 - 02:42 PM

It seems I'm getting somewhere... albeit only a little step in the right direction. I did as advised and wrote the following:

	for(index = 0; index < inNavn.size(); index++){												//henter ut hver element i lagringsvektoren for navn
		nyStudent(inNavn.at(index));															//setter studentens navn
	}
	for(index = 0; index < innStudnr.size(); index++){											//henter ut hver element i lagringsvektoren for studentnummer
		for(index = 0; index < inNavn.size(); index++){											//henter ut hver element i lagringsvektoren for navn
			setStudentnr(inNavn.at(index), innStudnr.at(index));								//setter studentens studentnummer
		}
	}
	for(index = 0; index < inNavn.size(); index++){												//henter ut hver element i lagringsvektoren for navn
		for(index = 0; index < innKarakter.size(); index++){									//henter ut hver element i lagringsvektoren for karakter
			setKarakter(inNavn.at(index), innKarakter.at(index));								//setter studentens karakterer
		}
	}
	for(index = 0; index < studenter.size(); index++){
		cout << " Contents of the studenter-vector: " << studenter[index].getNavn() << endl;					//viser navn
		cout << " Contents of the studenter-vector: " << studenter[index].getStudentnummer() << endl;			//viser studentnummer
		cout << " Contents of the studenter-vector: " << studenter[index].getKarakter() << endl;				//viser karakterer
		cout << endl;
	}


Using the cout's above to view the contents, it now seems that the "studenter" -vector contains the correct information. However, when using the code below, wich occurs troughout my main-part to get at the contents, I get absoloutly nothing. It will not output anything at all. However when the user inputs something, it will output what the user entered...
for (int indeks = 0; indeks < data.getAntStudenter(); indeks++)		//lister opp og viser tilgjengelige studenter
{
	const Student *studenten = data.getStudent(indeks);				//går igjennom indeksen til hvert element
	cout << " <" << (indeks + 1) << ">";							//indeksnummer
	cout << " :: " << studenten->getStudentnummer() << " :: ";		//studentnummer
	cout << studenten->getNavn() << endl;							//navn
}



I really appreciate all the help I've recived thus far!

Thank you and Thanks in advance
William

This post has been edited by hk416: 13 October 2008 - 02:54 PM

Was This Post Helpful? 0
  • +
  • -

#10 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 280
  • View blog
  • Posts: 1,787
  • Joined: 20-September 08

Re: Adding data to a vector from file while still using the original set/g

Posted 14 October 2008 - 05:38 AM

Quote

I really appreciate all the help I've recived thus far!

Thank you and Thanks in advance
William


Well ... if you really want to use push_back ...

This could get you started on that track ...

1. Permits keyboard entry to start a new record ...

2. Shows records in memory on screen

3. Writes vector of records to file with CSV format

4. Reads file back into a new vector of records

Just for you :)

Shalom,

David

/*
	The basic gist of the program is that the user can input data about a person, 
	here; name and a number. The name (varible "navn") gets sent to the 
	"nyStudent" -function, inserted into the object "nyStudent" of type "Student", 
	then the object gets pushed into the vector "studenter". Now the number 
	(variable "studentnummer") can be added to the specified name "navn" 
	if found in the vector.
	
	Now for the problem at hand; how do i achive the exact same thing, 
	but not from user input in the program but rather from a file instead?. 
	In the program the user has the option to save all of the data into a CSV file. 
	Then at a later time, the user can opt to load the data back into the 
	"studenter" -vector to continue working on it.
	
	Now i've figured out how to read and split up the data. My problem is 
	getting that data into the "studenter" -vector again in the correct way, 
	so that when i run my code snippet for getting and displaying the 
	variables, it comes out correct.
	
	Any helpful advice on this issue would be very much appreciated!
*/


// a simple example ...

#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <cctype>

// Globals ...
const char thisTerm[] = "fall.txt"; // file name for term records

using namespace std;

class Student
{
private:
	string name, 
		   id;
public:
	// constructors ...
	Student(){;} 
	Student(string nam, string num ) { name=nam; id=num; } 
	// setters ...					 
	void setName(string nam){ name = nam; }
	void setID(string num) { id = num; }
	// getters ...
	string getName() { return name; }
	string getID() { return id; }  
};

void newStud( vector< Student > &term )
{
	char reply;
	string nam, num;
	for(;;)
	{
		cout << "\nName : ";
		getline(cin,nam);
		cout << "ID   : ";
		getline(cin,num);
		term.push_back( Student(nam,num) );
		
		cout << "\nMore y/n ? ";
		reply=cin.get();
		cin.sync();
		if ( toupper(reply)=='N' ) break;
	}
}

void showStuds( vector< Student > &term )
{
	for( int i=0; i< term.size(); ++i )
	{
		cout << i+1 << ".\n"
			 << "Name   : " << term[i].getName() << endl
			 << "Number : " << term[i].getID() << endl;
	}   
}

int fileStuds( vector< Student > &term )
{
   ofstream fout;
   fout.open( thisTerm ); // recall thisTerm is a Global variable
   if ( !fout.is_open() ) return -1; // report error condition ...
   
   // else ...
   for(int i=0; i<term.size(); ++i) 
		fout << term[i].getName() << "," << term[i].getID() << endl;
   fout.close();
   return 0; // report success ...  
}

int getFileStuds( vector< Student > &term )
{
   ifstream fin;
   fin.open( thisTerm ); // recall thisTerm is a Global variable
   if ( !fin.is_open() ) return -1; // report error condition ...
   
   // else ...
   int i;
   string nam, num;
   vector< Student >temp;
   term = temp; // set to null ...
   for( i=0; getline( fin, nam, ',' ); ++i ) 
   {
		getline( fin, num, '\n' );
		term.push_back( Student(nam,num) );
		
   }	
   fin.close();
   return i; // report success ...  
}

int main()
{
	// create a 'fall vector' to hold student names and ids for Fall Term
	vector <Student > fall; 
	char reply;
	for(;;) // loop forever ... until break ...
	{
		cout << "\nWhat do you want to do ?\n\n"
			 << "\t1. Add a new student name and id ? \n"
			 << "\t2. See all in memory at present ? \n"
			 << "\t3. Update file with data currently in memory ? \n"
			 << "\t4. Load in data from file ? \n"
			 << "\t5. Exit program ? ";
			 
		reply = cin.get();
		cin.sync();

		if (reply=='1')
		{
			newStud( fall );
		}
		else if (reply=='2')
			showStuds( fall );
		else if (reply=='3')
		{
			int condition = fileStuds( fall );
			if ( condition == 1 )
			{
				cout << "\nError attempting to open file.\n";
				system("pause");
				return -1;
			}
		}	   
		else if (reply=='4')
		{
			int condition = getFileStuds( fall );
			if (  condition == -1 )
			{
				cout << "\nError attempting to open file.\n";
				system("pause");
				return -1;
			}
			else 
				cout << "\nThere are " << condition
					 << " student records in the files.\n" << endl;
		}
		else if (reply=='5') break;
	}

	system( "notepad fall.txt" );
}


This post has been edited by David W: 14 October 2008 - 06:01 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1