Problem with loop and reading input file

I am writing a program for an assignment, and we have to read in a .csv file that contains information about various chemicals and store that information in Chemical objects and create an array of the objects. Here is a small sample of what the input file looks like:

Chemical,CAS #/Comp ID,Clean Air Act Chemical,Classification,Metal,Metal Category,Carcinogen,Form Type,Unit of Measure,Risk Factor
STYRENE,100425,YES,NON-PBT,NO,0,YES,R,Pounds,Unknown
N-METHYLOLACRYLAMIDE,924425,NO,NON-PBT,NO,0,NO,R,Pounds,Unknown
METHYL METHACRYLATE,80626,YES,NON-PBT,NO,0,NO,R,Pounds,Unknown
FORMALDEHYDE,50000,YES,NON-PBT,NO,0,YES,R,Pounds,Unknown
ETHYL ACRYLATE,140885,YES,NON-PBT,NO,0,YES,R,Pounds,Unknown
BUTYL ACRYLATE,141322,NO,NON-PBT,NO,0,NO,R,Pounds,Unknown
ACRYLONITRILE,107131,YES,NON-PBT,NO,0,YES,R,Pounds,Unknown
ACRYLIC ACID,79107,YES,NON-PBT,NO,0,NO,R,Pounds,Unknown
ACRYLAMIDE,79061,YES,NON-PBT,NO,0,YES,R,Pounds,Unknown
NAPHTHALENE,91203,YES,NON-PBT,NO,0,NO,A,Pounds,Unknown
ETHYLBENZENE,100414,YES,NON-PBT,NO,0,NO,A,Pounds,Unknown
AMMONIA,7664417,NO,NON-PBT,NO,0,NO,R,Pounds,Unknown
LEAD,7439921,YES,PBT,YES,1,YES,R,Pounds,Unknown
COPPER,7440508,NO,NON-PBT,YES,1,NO,R,Pounds,Unknown
SILVER COMPOUNDS,N740,NO,NON-PBT,YES,1,NO,R,Pounds,Unknown
NITRIC ACID,7697372,NO,NON-PBT,NO,0,NO,R,Pounds,Unknown
NITRATE COMPOUNDS,N511,NO,NON-PBT,NO,0,NO,R,Pounds,Unknown
METHANOL,67561,YES,NON-PBT,NO,0,NO,R,Pounds,Unknown
HYDRAZINE,302012,YES,NON-PBT,NO,0,YES,R,Pounds,Unknown
FORMALDEHYDE,50000,YES,NON-PBT,NO,0,YES,R,Pounds,Unknown
COPPER COMPOUNDS,N100,NO,NON-PBT,YES,1,NO,R,Pounds,Unknown
CHLORINE,7782505,YES,NON-PBT,NO,0,NO,R,Pounds,Unknown
CHLORODIFLUOROMETHANE,75456,NO,NON-PBT,NO,0,NO,R,Pounds,Unknown
DIISOCYANATES,N120,YES,NON-PBT,NO,0,NO,R,Pounds,Unknown
"TOLUENE-2,4-DIISOCYANATE",584849,YES,NON-PBT,NO,0,YES,A,Pounds,Unknown
ETHYLENE GLYCOL,107211,YES,NON-PBT,NO,0,NO,A,Pounds,Unknown
POLYCYCLIC AROMATIC COMPOUNDS,N590,YES,PBT,NO,0,YES,R,Pounds,Unknown


I'm having problems reading in the data. This is the code I have so far:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include "Chemical.h"
#include "ChemicalData.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

using namespace std;

Chemical chemArray[ARRAY_SIZE]; 

void inputdata()
{
    string  fileNameIn;
	ifstream inFile;
	bool worked = false;
    int count = 0;
	
    //Asks user to input name of file to read from, open the file. If file fails to open, the user is notified, otherwise the code continues
    do
    {
		cout << "Enter name of file to read from:" << endl;
		cin >> fileNameIn;
		
		inFile.open (fileNameIn.c_str());
        
        if (inFile.fail())
        {
            cerr << "There was an error opening the file. Check the file and try again." << endl;
		inFile.clear();
		inFile.ignore(80, '\n');
		worked = false;
	}
	else
	  worked = true;
	} while (!worked);
    
    string line;
    while(getline(inFile, line))
    {
         stringstream linestream(line);
         string c_name, c_number, c_cleanair, c_classification, c_metal, c_metalcategory, c_carcinogen, c_formtype, c_unitmeasure, c_riskfactor;
         
        getline(linestream, c_name, ',');
        getline(linestream, c_number, ',');
        getline(linestream, c_cleanair, ',');
        getline(linestream, c_classification, ',');
        getline(linestream, c_metal, ',');
        getline(linestream, c_metalcategory, ',');
        getline(linestream, c_carcinogen, ',');
        getline(linestream, c_formtype, ',');
        getline(linestream, c_unitmeasure, ',');
        linestream>>c_riskfactor;
         
         //Creates a temporary Chemical object, and then places that object into the array
         Chemical temp_chem (c_name, c_number, c_cleanair, c_classification, c_metal, c_metalcategory, c_carcinogen, c_formtype, c_unitmeasure, c_riskfactor);
         
         chemArray[count] = temp_chem;
         count++;

     }
    
    inFile.close();
    
    for (int j=0; j<count; j++)
        cout<<chemArray[j].getName()<<endl;

}


I placed the for loop at the end so I could test that the data was being properly stored.

The main problem I am having is that the code only reads the first line of the file and then exits the program. So my output is just one chemical name.
Second, I seem to be having problems with ignoring the first line of the file. The first line is just header information, so I don't want to store this info in a Chemical object, but if I try to use inFile.ignore(100, '\n') for example, the program always ignores 100 characters, regardless of whether it reaches a new line.
Thirdly, as can be seen from the code to get the last element of the line, I used linestream>>c_riskfactor. If I try to use getline(linestream, c_riskfactor) it does not work for some reason, perhaps the same reason the new line character does't work for ignore. However, the data is clearly on separate lines so there must be new line characters in the file? This problem is not as big a problem as the other two, but still annoying.
Finally, I will need to figure out how to ignore the comma delimiter for Chemicals such as "TOLUENE-2,4-DIISOCYANATE", which appear between quotes, but I haven't even been able to get to this step yet.

I've only posted the one file of code, as that is where everything happens as of now. The other header and definition files are extremely small, and I didn't think they would be relevant to the problem, but if they might be needed I can post them as well.

Thank you
To ignore the first line of the file, you could just insert a getline, immediately before the start of the while loop at line 39:
 
    getline(inFile, line); // ignore first line 


I'm not sure why the program only reads the first line and then exits.
I tried to run a simplified version of the code, I had to remove all references to the Chemical object, and possibly the error is in the part of the code which I deleted.
Ok, I tried doing the same by removing all references to the Chemical object, and just added a cout<<c_name statement after the getline for the c_name variable to check the input, and the program is still only reading the first line. Also, when adding a getline before the while loop to ignore the first line, after I type in the file name, the program just exits and nothing happens.
Could there possibly be an issue with my system that is causing the program to not run correctly? (I'm on a Mac using Xcode and running the program through Terminal). The only thing I can deduce so far is that there seems to be some kind of issue any time I encounter a new line in the input file.
Out of interest, this is the version which ran successfully for me. However I'm on a Windows XP machine.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <iomanip>

using namespace std;

void inputdata();

int main()
{   
    inputdata();
    
    return 0;
}

void inputdata()
{
    string  fileNameIn = "chemical.txt";
    ifstream inFile;
            
    inFile.open (fileNameIn.c_str());
    
    if (inFile.fail())
    {
        cerr << "There was an error opening the file. Check the file and try again." << endl;
        return;
    }

    string line;
    getline(inFile, line); // ignore first line
        
    while(getline(inFile, line))
    {
         stringstream linestream(line);
         string c_name, c_number, c_cleanair, c_classification, c_metal, 
             c_metalcategory, c_carcinogen, c_formtype, c_unitmeasure, c_riskfactor;
         
        getline(linestream, c_name, ',');
        getline(linestream, c_number, ',');
        getline(linestream, c_cleanair, ',');
        getline(linestream, c_classification, ',');
        getline(linestream, c_metal, ',');
        getline(linestream, c_metalcategory, ',');
        getline(linestream, c_carcinogen, ',');
        getline(linestream, c_formtype, ',');
        getline(linestream, c_unitmeasure, ',');
        linestream>>c_riskfactor;
         
        string bar = "| ";
         
        cout << left 
             << setw(29) << c_name           << bar
             << setw(8)  << c_number         << bar
             << setw(3)  << c_cleanair       << bar
             << setw(8)  << c_classification << bar
             << setw(3)  << c_metal          << bar
             << setw(2)  << c_metalcategory  << bar
             << setw(4)  << c_carcinogen     << bar
             << setw(2)  << c_formtype       << bar
             << setw(8)  << c_unitmeasure    << bar 
             << setw(8)  << c_riskfactor     << endl;
     }
    
    inFile.close();   
}
Even after running your version of the code, I'm still getting the same exact problems as I had with my code. Now I definitely am thinking there is probably something wrong with my computer that is causing the problem.
It could be something to do with the input file. I'm not sure, it might be an unexpected character at the end of line. On windows, a text file generally has a pair of characters "\r\n" as the line separator, I don't know about the Mac.
Yea, I can't figure out what the problem is. I connected to my school's VPN and uploaded the files to and ran them from one of our Linux servers, and it worked fine. I don't know how to figure out why my computer won't run the program correctly. At least I have the VPN option, it's just a bit annoying to do so.

EDIT: Ok, solved my own problem. It was a problem with the characters at the end of the line. Mac OS X is Unix based, and uses "\n" at the end of a line. But after doing some searching, I found that there is a problem with Excel on Macs that saves .csv files with "\r".
Last edited on
Topic archived. No new replies allowed.