Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Using ifstream to open multiple files

  1. Apr 28, 2014 #1
    I am currently working on a C++ program for school. I am actually not finding too much difficulty in constructing the functions, enum-types, arrays and structs, however, I am finding great difficulty in using on ifstream variable to open multiple files.

    I have posted the entire code that I have so far (even though I have pinpointed the issue to not properly opening the second file in ifstream).

    I spent a couple of hours getting rid of certain functions/procedures, loops and variables and I get the same output (if what I removed doesnt crash it). I also get the same output whether I "open" the second file or not (meaning I removed all of the code for it and got the same output).

    Here is the code (it's not finished because I am stuck on this file issue but hopefully my comments give you a clear enough picture to help). It's a bit messy since I am now in debug mode versus program mode:

    Code (Text):
    /* Trevor Novak - April 9, 2014 - "Bodylastics"
         This program will construct an array of structs to determine
         the resistance of corresponding resistance bands. It will also
         calculate an individuals weight and provide an appropriate band. */
    using namespace std;

    const string SENTINEL = "stop";
    enum bandType {YELLOW, GREEN, RED, BLUE, BLACK};

    struct bandRecord
           string bandcolor;
           int weight;
           bool is_used;

    /* Function Prototypes */

    void setup(ifstream&, bandRecord[]);
    void getBands(ifstream&, bandRecord[]);
    bandType str_to_color(const string&);
    void printBands(ofstream&, const bandRecord[]);
    int totalResistance(const bandRecord[]);
    void resetBands(bandRecord[]);
    void weight_to_bands(int, bandRecord[]);

    int main()
        bandRecord myList[BLACK+1];
        ifstream inData;
        ofstream outData;
        string bandcolor;

      inData.open("setupData.txt"); // Open setupData File
      if (not inData){
         cout << "Can't open data.txt" << endl;
         system ("pause");
         return 1;}

      outData.open("outData.txt"); // Generate outData File
      if (not outData){
         cout << "Can't open output.txt" << endl;
         system ("pause");
         return 1;}

        setup(inData, myList); // Calls the setup procedure.
        /* The follow lines are tests to find the code errors */
        cout << myList[1].bandcolor << " " << myList[1].weight << endl;
        cout << myList[4].bandcolor << " " << myList[4].weight << endl;


      inData.open("bandData.txt"); // Open bandData File
      if (not inData){
         cout << "Can't open data.txt" << endl;
         system ("pause");
         return 1;}[/b]
        getBands(inData, myList); // Call getBands procedure.

        /* The follow lines are tests to find the code errors */
        cout << myList[2].is_used << " " << myList[2].bandcolor << endl;
        cout << myList[1].is_used << " " << myList[1].bandcolor << endl;
        cout << myList[4].is_used << " " << myList[4].bandcolor << endl;
        printBands(outData, myList); // Call printBands procedure.
    return 0;


    /* Function/Procedure Definitions */

    /* This procedure will read in data from a text file
       into a struct called bandRecord and constructs an
       array of type bandRecord. The array is indexed
       by the enum type, bandType. */

    void setup(ifstream& inData, bandRecord myList[])
        for(int i=YELLOW; i <= BLACK; i++)
          inData >> myList[i].bandcolor >> myList[i].weight;
          myList[i].is_used = false;

    /* This procedure will read in band colors as tempString.
       It will then call by value str_to_color(tempString)
       to assign its (enum type) value to a bandType tempBand.
       It will then set the .is_used flag to true according
       to index of the temporary bandType. */

    void getBands(ifstream& inData, bandRecord myList[])
     string tempString;
     bandType tempBand;

     inData >> tempString;
            tempBand = str_to_color(tempString);
            myList[tempBand].is_used = true;

    /* This function will create a temporary character array
       based on the contents of tempString. The switch will then
       determine the first letter of the string and assign tempBand
       the value of the corresponding enum-type. To resolve the issue
       of black and blue, upon encountering 'b' it will test the third
       letter to determine if it is "blAck" or "blUe". */

    bandType str_to_color(const string& tempString)
     bandType tempBand;

           case 'y': tempBand = YELLOW;
           case 'g': tempBand = GREEN;
           case 'r': tempBand = RED;
           case 'b':
                     if(tempString[2] == 'u')
                     tempBand = BLUE;
                     if(tempString[2] == 'a')
                     tempBand = BLACK;

          return tempBand;

    void printBands(ofstream& outData, const bandRecord myList[])
       for(int i=YELLOW; i <= BLACK; i++)
          if(myList[i].is_used == true)
             outData << myList[i].bandcolor << myList[i].weight << endl;

    int totalResistance(const bandRecord[])
    void resetBands(bandRecord[])
    void weight_to_bands(int, bandRecord[])
    I'll continue working on it and thank you for your time and assistance.

    Last edited: Apr 28, 2014
  2. jcsd
  3. Apr 28, 2014 #2

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    If you call std::if stream::eek:pen on an already connected stream, the open call will fail and the stream will be marked as failed.

    You need to close the stream before you (re)open it. It's also a good idea to call clear between calling close and open.
  4. Apr 28, 2014 #3
    Hey DH! Been reading your posts for the last 8 years ;) In the posted code I have a close after the initial file open (It's a mess to read right now), however, when I had used inData.clear(); it was causing it to crash.

    I just changed the heading of the getBands procedure from
    Code (Text):
     getBands(ifstream&, bandRecord[]) to getBands[istream&, bandRecord[])
    so that I could use
    Code (Text):
    to test an input.

    I have now discovered an issue with getBands procedure when it calls
    Code (Text):
    . As an example, I typed in "red" and it crashed. Tried "blue" and it crashed. So, I appear to have an issue with that procedure and perhaps that is why the data wasn't read in from the second file.

    Going to continue troubleshooting. I am sure it is something silly.

    Thank you for your advice, I appreciate it.
  5. Apr 28, 2014 #4
    HAHA just found it!

    I was returning the value inside the switch statement but wasn't returning a value of bandType at before the end of the function. So, I wasn't passing anything in the call by value.

    Coding is FUNSTRATING!
  6. Apr 28, 2014 #5


    Staff: Mentor

    No doubt just a copy/paste typo, but in what you changed to, the first bracket right after getBands should be a parenthesis.
    Code (Text):
    getBands[B]([/B]istream&, bandRecord[])
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook