0

I'm working on a project for school. It's relatively simple, at least it appears to be: take file one (named sd, or student data, in the nomenclature of my code below), which contains student ID data and compare it to file two (named hc, the name of my college). File two contains a list of all active courses at my college, and has additional information that is not contained in file one: the number of course hours for each class, and a special code that indicates what sort of course it is. The goal is to replicate all the data in the student ID file and append each line with the relevant course hours and special code. Here's an example below:

Sample of a line from file 1 (SD):

20424297 1142 PSYCH 22000 W -1

Sample of a line from file 2 (HC):

PSYCH 22000 3.0 RLA

The goal is to take the 6k lines from SD, match them with the course data from HC (around 13k lines), and output an additional 6k in a third file that looks like this:

20424297 1142 PSYCH 22000 W -1 3.0 RLA

Our course is a relatively introductory CS course, and we've been exposed to only a few basic concepts in CS and C++. This project is intended to be solved using only the very rudimentary ideas we've discussed (file streams, while loops, for loops, etc). So after much thought, I realized that a series of nested while loops ought to be able to resolve this. Have one while loop active while I stuff data from file 1's input stream into variables, and have another while loop active that will open up file two, searching through the entirety of that data, and output a line when a match is made. I know it's somewhat inefficient to have the entirety of file 2 opened up and searched through for each line of file one, but our professor explicitly stated that speed and efficiency are not the priorities for this assignment.

Here is the code I created below:

#include <fstream>
#include <iostream> // INCLUDED FOR TESTING ERROR STATEMENTS
using namespace std; 

int main ()
{
   ifstream sdStream;
   ifstream hcStream;
   ofstream outputStream; 

   sdStream.open ("StudentData.tsv"); // use this to take in data from SD file
   hcStream.open ("HunterCourses.tsv"); // use this to open stream for HC file 
   outputStream.open("File1.tsv"); // this will be the csombine data file created by this output stream. 

        //Student Data String Objects
   string eiD; 
   string semester;
   string subject;
   string coursenumSD;
   string grade;
   string gradeNum;

   //Hunter College Data String Objects
   string subjectHC;
   string coursenumHC;
   double gpaHC;
   string codeHC;

   // bool streamactive = sdStream >> eiD >> semester >> subject >> coursenumSD >> grade >> gradeNum; 

   // USE THE BELOW AS A STANDARD TRANSFER DATA TEMPLATE
   // while (sdStream >> eiD >> semester >> subject >> coursenumSD >> grade >> gradeNum)
   // {
   // hcStream >> subjectHC >> coursenumHC >> gpaHC >> codeHC;   
   // outputStream << endl << eiD + ' ' << semester + ' ' << subject + ' ' << coursenumSD + ' ' << grade + ' ' << gradeNum + ' ';
   // }


   while (sdStream >> eiD >> semester >> subject >> coursenumSD >> grade >> gradeNum) // while stream from SD file is open, execute below
   {
      while (hcStream >> subjectHC >> coursenumHC >> gpaHC >> codeHC) // while stream from HC file is open, execute below 
      {
         if ((coursenumHC == coursenumSD) && (subject == subjectHC)) // while identifying info from file 1 = date from file 2, out put the below
         {
            outputStream << endl << eiD + ' ' << semester + ' ' << subject + ' ' << coursenumSD + ' ' << grade + ' ' << gradeNum + ' ' << gpaHC + ' ' << codeHC + ' ';
         }
      }   
   }

   outputStream.close(); sdStream.close(); hcStream.close();
   return 0;
}

Hopefully this will not to be too onerous to read though. For readability's sake, here is the loop in question:

   while (sdStream >> eiD >> semester >> subject >> coursenumSD >> grade >> gradeNum) // while stream from SD file is open, execute below
   {
      while (hcStream >> subjectHC >> coursenumHC >> gpaHC >> codeHC) // while stream from HC file is open, execute below 
      {
         if ((coursenumHC == coursenumSD) && (subject == subjectHC)) // while identifying info from file 1 = date from file 2, out put the below
         {
            outputStream << endl << eiD + ' ' << semester + ' ' << subject + ' ' << coursenumSD + ' ' << grade + ' ' << gradeNum + ' ' << gpaHC + ' ' << codeHC + ' ';
         }
      }   
   }

The output of this is a single line, successfully matching the first line of file 1 (SD) with the pertinent data in file 2 (HC). And that's it. The loop ends. I showed this code to a few other folks who told me that the issue was that when HC's input stream opens up for the 2nd line of SD, it opens up where it left off. I'm not sure that's the case, but it seems plausible. Is there anyway I can ensure this loop cycles through from the beginning of file 2 (HC) to the end of file 2 for each line of file one? I've tried everything I can think of, from opening and closing the input stream for file 2 within the loops to experimenting with the .eof() command - though I'm not sure i'm using it at all correctly.

Chris T
  • 453
  • 1
  • 6
  • 17
  • 1
    You have two files, `sdStream` and `hcStream`. You read the first portion of data from `sdStream`, then you read the entire `hcStream` file. By the time you are ready to process the second portion of data from `sdStream`, you are firmly at the end of `hcStream`. There's no more data to read. It won't go back to the beginning of the file. So far you've got it right. Perhaps one of your other attempts was closer to working code? Show some of the variants you have tried. – n. m. could be an AI Feb 21 '16 at 21:22
  • nm, thank you for your helpful comment - my other attempts yield the exact same output. I did create a loop, when I working on this project last week, that successfully reproduced all of sdStream in my output file (check under "USE THE BELOW AS A STANDARD TRANSFER DATA TEMPLATE" and it was that thinking that lead me to try the same sort of loop with hcStream. Thank for you identifying the issue with hcStream - I'm trying to think what I can use to have a loop start hcStream from the beginning of the file...I've heard that I can use .clear()? – Chris T Feb 21 '16 at 21:33
  • Don't use comments to show substatntial code. Please use the [edit link](http://stackoverflow.com/posts/35542149/edit) at the bottom of the post to make corrections and additions. – n. m. could be an AI Feb 21 '16 at 21:36
  • @ChrisT "*This project is intended to be solved using only the very rudimentary ideas we've discussed (file streams, while loops, for loops, **etc**)*" -- It is the *etc.* that you should expand on, since we are not in your class. What about arrays? – PaulMcKenzie Feb 21 '16 at 21:36
  • I believe arrays and functions are beyond the scope of this assignment. Other than that, my professor has not mentioned anything else I can't use, so I'm assuming stuff like .eof() and clear() are fair game, though I hardly know how to utilize them. – Chris T Feb 21 '16 at 21:37
  • 1
    This is a very clumsy assignment, given what you're told to use, quite honestly. You would have to `rewind` to the top of the second file and start all over. http://stackoverflow.com/questions/28331017/rewind-an-ifstream-object-after-hitting-the-end-of-file – PaulMcKenzie Feb 21 '16 at 21:39
  • OT: If you don't know how to utilise certain functions (or don't even know which are available to you) then you should check out some reference, like: http://en.cppreference.com/w/ – Daniel Jour Feb 21 '16 at 21:58
  • So I eventually was able to utilize .clear() and .seekg() to reset hcStream. I placed these commands right under the first loop and it worked perfectly. Thank you all, especially PaulMcKenzie for pointing me to these aspects of fstream. My professor also emailed us and let us know we could use these. – Chris T Feb 21 '16 at 23:16

0 Answers0