Using ifstream to open multiple files

  • Thread starter Thread starter ActionPotential
  • Start date Start date
  • Tags Tags
    files Multiple
Click For Summary
The discussion centers on troubleshooting a C++ program that involves reading data from multiple files using an ifstream variable. The user is experiencing difficulties specifically with opening a second file, "bandData.txt," after successfully opening the first file, "setupData.txt." Despite attempts to debug the issue, including removing functions and variables, the output remains unchanged, indicating that the second file is not being accessed correctly.Key points include the importance of closing the ifstream before reopening it for the second file, as failing to do so can cause the stream to fail. The user also encountered issues with the getBands procedure, which crashes when processing input strings for band colors. A critical mistake was identified in the str_to_color function, where a return statement was missing, leading to incorrect behavior. The user has since made adjustments to the function signatures and is continuing to troubleshoot the program, noting the challenges of coding as both fun and frustrating.
ActionPotential
Messages
60
Reaction score
4
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 doesn't 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:
/* 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. */
       
#include<iostream>
#include<fstream>
#include<iomanip>
#include<string>
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.close(); 
    

   [b]/* -- THIS IS THE PROBLEM BELOW - I NEED DATA
      FROM THIS FILE AND IT IS NOT OPENING */

  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.
	
system("pause");
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; 
 
	while(inData)
	{ 
		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;

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

      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.

Regards,
ActionPotential
 
Last edited:
Technology news on Phys.org
If you call std::if stream::open 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.
 
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:
 getBands(ifstream&, bandRecord[]) to getBands[istream&, bandRecord[])
so that I could use
Code:
 cin
to test an input.

I have now discovered an issue with getBands procedure when it calls
Code:
 str_to_band(tempString);
. 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.
 
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!
 
ActionPotential said:
I just changed the heading of the getBands procedure from
Code:
 getBands(ifstream&, bandRecord[]) to getBands[istream&, bandRecord[])
so that I could use
Code:
 cin
to test an input.
No doubt just a copy/paste typo, but in what you changed to, the first bracket right after getBands should be a parenthesis.
Code:
getBands[B]([/B]istream&, bandRecord[])
 
Learn If you want to write code for Python Machine learning, AI Statistics/data analysis Scientific research Web application servers Some microcontrollers JavaScript/Node JS/TypeScript Web sites Web application servers C# Games (Unity) Consumer applications (Windows) Business applications C++ Games (Unreal Engine) Operating systems, device drivers Microcontrollers/embedded systems Consumer applications (Linux) Some more tips: Do not learn C++ (or any other dialect of C) as a...

Similar threads

  • · Replies 8 ·
Replies
8
Views
2K
Replies
6
Views
2K
Replies
10
Views
2K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 8 ·
Replies
8
Views
6K
  • · Replies 23 ·
Replies
23
Views
2K
  • · Replies 89 ·
3
Replies
89
Views
6K
Replies
5
Views
2K
Replies
5
Views
2K
  • · Replies 9 ·
Replies
9
Views
5K