3 Replies - 2108 Views - Last Post: 11 November 2009 - 03:42 AM Rate Topic: -----

#1 ryujin89  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 09-November 09

File I/O with array/vector then sort?

Posted 10 November 2009 - 12:02 AM

Figure I might as well go ahead and clear up that this is obviously a school assignment. I have completed a somewhat decent amount of code (not saying I have a lot of faith in it's correctness tho) and need assistance to figure the rest out. I'm at a complete loss due to teacher and book not really covering material in a way to prepare for the assignment. I have looked over the tutorials for I/O on this site as well as others and if I need to change things, I'm wide open for assistance. I did attempt to figure out as much as I could, but I'm stuck. Thanks in advance for anyone who takes time to assist me. I greatly appreciate it.

To clear things up from the start, here are the instructions:

The program is to take a text file, students.txt, containing information about the currently-enrolled students in a school. Each
line represents a record for a different student and contains the student's identification number (eight digits), credit hours
completed, and grade point average. A sample line follows:

10082352 66 3.04

Program is supposed to have the identification number and grade point average for each student in the file copied to one of four
different text files based on the number of credit hours completed:

Less than 32 freshmen.txt
32 to 63 sophomores.txt
64 to 95 juniors.txt
96 or more seniors.txt

Next is to write the identification number and grade point average of each student on a single line (one line per student) in the
appropriate file. For example, since the student mentioned above has completed 66 credit hours, the following would be
added to the file juniors.txt:

10082352 3.04


The number of students in the original file is unknown, so the program will need to read these records in until you reach the end of
the file.

Also, no student should have a negative number of credit hours, and the maximum number of credit
hours that a student can accumulate is 250. If the program encounters a student record with an erroneous number of
credit hours, write the entire record for that student (identification number, credit hours, and grade point average) to the
file hoursError.txt rather than any of the four aforementioned files. The lowest grade point average a student may have is 0.0, and the highest grade point average a
student may have is 4.0. If the program encounters a student record with an erroneous grade point average, write the
entire record for that student to the file averageError.txt rather than any of the four aforementioned files.As was previously stated, the student's identification number should be eight digits. If the program
encounters a student record with an identification number of fewer or greater than eight digits, write the entire record for
that student to the file identError.txt rather than any of the four aforementioned files.Assume that an identification number error has highest precedence, then the
number of credit hours completed, then the grade point average. Don't write a student record to multiple error files: only
the one that has the highest precedence should receive the record.

I'm going in the direction that I believe it needs to have the input file made into a dynamic array, but not sure how to do that.

I am now at the point that I would need to create an array or vector that would read in the line from students.txt and then be able to sort it to different output files based on the 2nd column of numbers.

ie.
say the line is 10082352 66 3.04

Next is to write the identification number and grade point average of each student on a single line (one line per student) in the
appropriate file.

For example, since the student mentioned above has completed 66 credit hours, the following would be
added to the file juniors.txt based on the criteria for sorting listed in the 1st post:

10082352 3.04


Here is my code thus far

#include <fstream>
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;


int main()
{
	  ifstream students("Students.txt");
	  if (students.fail())
	  {
	  cout<< "Input file opening failed.\n";
	  exit(1);
	  }

	  int count=0;
	  char carray[1000];
	  while (!students.eof())
	  {
	  students.getline(carray,10000);
	  cout << carray <<endl;
	  count++;
	  }
//just to test and see if loop is working I print it to the console.
	  cout << "The number of records found in the file are: " << count << endl;


ofstream freshmen("freshmen.txt");
ofstream sophomores("sophmores.txt");
ofstream juniors("juniors.txt");
ofstream seniors("seniors.txt");

//test to show output file creation and writing are working
if (freshmen.is_open())
  {
	freshmen << "The number of records found in the file are: " << count << endl;
	freshmen.close();
  }
  else cout << "Unable to open file";

}



To clear up where I'm at, I need assistance in figuring out how to get the input file data into either an array or vector and then sort it to its different respective output files.

There is also possibility that the input file may have a student ID with more than 8 numbers as well as the other two columns having a varying number digits in each column (which will also affect which output file it will be sent to).

// Edited to put this part in.

not sure exactly how to use it, but could something like

 
int studentID[count];
int creditHours[count];
int gpa[count];



work to create an array that will vary based on the number of lines in the file?

//End edit


Thanks to all who have the patience to assist me.

This post has been edited by ryujin89: 10 November 2009 - 12:45 AM


Is This A Good Question/Topic? 0
  • +

Replies To: File I/O with array/vector then sort?

#2 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 856
  • View blog
  • Posts: 2,339
  • Joined: 20-August 07

Re: File I/O with array/vector then sort?

Posted 10 November 2009 - 06:20 AM

As for arrays vs. vectors; when it comes to solving real problems in C++, raw arrays are rarely used because they're a blunt tool full of caveats and gotchas. Most of the time, a vector will do everything you need far more easily and efficiently - including the ability to resize itself to fit as many items as you need (Something which raw arrays do not do easily).

As for reading the file, the first issue I can see with your code is that you are reading "while not EOF" - put simply, this doesn't do what you probably think it does (EOF is a file state flag, and not an indicator of whether there is any data to be read in a file - in other words, a completely empty file will not have EOF set until after a failed read attempt)
You need to use and idiom of "Read the file while there is still data to be read"; and the getline() function will do this for you

std::ifstream students("students.txt");
std::string input;
while( std::getline(students, input) )
{
    //TODO: Parse input.
} 



For parsing a line of data once you have retrieved it from your file, one way is to use a kind of buffer called a stringstream; These work to the same interface as a file stream or cin/cout - the difference is that its data is based on a string rather than some external input.
#include <sstream>
// .. etc ..

    std::string input = "12345678 50 3.2";
    std::istringstream buffer(input);
    int id_number;
    int credit_hours;
    double grade_points;

    if( buffer >> id_number >> credit_hours >> grade_points )
    {
        // Data parsed successfully
    }
    else
    {
        // Some error encountered.
    } 



To store your data, you're probably going to want a compound data type such as a struct or class to wrap your data up together. at the most primitive level, a struct is a bit like a blueprint for an entity in a database - holding different items of data together as data records.
struct student
{
    int id;
    int hours;
    double grade;
};

You can create student objects using the struct
    student my_student;
    my_student.id = id_number;
    my_student.hours = credit_hours;
    my_student.grade = grade_points; 


Having data neatly wrapped up in an object will make life easier storing data into a single vector
    std::vector<student> vec;
    vec.push_back( my_student ); 


push_back() will increase the size of the vector by one, and add a copy of my_student to the end of the vector. You will never need to worry manually resizing a vector so long as you use member functions such as push_back to insert new students.
Was This Post Helpful? 0
  • +
  • -

#3 ryujin89  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 09-November 09

Re: File I/O with array/vector then sort?

Posted 10 November 2009 - 09:23 PM

So due to this being my 1st class and I don't fully understand all of this, I'm lost. It's due in roughly 47 hours and as can be seen, I'm not even in the testing part to ensure it's working. I've worked on this for roughly 7.5 hrs per night every night for the past 4 days and I just can't wrap my mind around it.

I greatly appreciate the assistance. I have attempted to place your suggestions within my code where I thought it would go, but even after re-naming, and moving stuff around and other things I can't get it to work. My compiler (VS 2008) didn't want to accept the way you had things "formatted" for lack of better terms so I took out parts so it would remove those errors, but I still can't get them all to work down to where I can follow them through and figure them out.

Here is my code as of now.

#include <fstream>
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <sstream>

using namespace std;


int main()
{
	  std::ifstream students("students.txt"); 
	  std::string input;
	
	  if (students.fail())
	  {
		cout<< "Input file opening failed.\n";
		exit(1);
	  }

	  int count=0;
	  char carray[1000];
	  while (!students.eof())
	  {
		students.getline(carray,10000);
		count++;
	  }

	  ofstream freshmen("freshmen.txt");
	  ofstream sophomores("sophmores.txt");
	  ofstream juniors("juniors.txt"); 
	  ofstream seniors("seniors.txt");
	  
	  while( std::getline(students, input) )
		{
			std::string input = "12345678 50 3.2";
			std::istringstream buffer(input);
			int id_number;
			int credit_hours;
			double grade_points;
			
		if( buffer >> id_number >> credit_hours >> grade_points )
		{
		
		struct student
		{
		int id;
		int hours;
		double grade;
		};

		id = id_number;
		hours = credit_hours;
		grade = grade_points;

		std::vector<student> my_student;
		my_student.push_back( my_student );
		}

		else
		{
			cout<<"Error in processing file.\n";
			exit(1);
		}
		
	  }
	  
}


Was This Post Helpful? 0
  • +
  • -

#4 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 856
  • View blog
  • Posts: 2,339
  • Joined: 20-August 07

Re: File I/O with array/vector then sort?

Posted 11 November 2009 - 03:42 AM

The 'testing' phase when writing a program should happen constantly, as soon as you begin your implementation you should try to pick up any problems from each small change you make. adding an entire raft of big changes all at once will nearly always take longer in the amount of time you take trying to find where you've gone wrong.

If you're not sure how one of the examples I've posted works, try them as small standalone programs instead of just trying to jam everything in to your main project without any incremental thought towards your overall design or testing.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1