Strange issue using input streams

I'm reading in a .txt file, the first couple of lines are:

1
2
5
Burglar Earthquake Alarm John Mary


The first line is the number of variables which are listed in the second line.
When reading in the second line i am using stringstream to break the line up into individual variables and store them. my code is:

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
int main(int argc,char* argv[])
{
	int numVars;
	int varsRead=0;
	string String;
	string token;
	vector<double> probTrue;
	int i;
	int j;
		
	ifstream fin(argv[1]);
		stringstream iss;
		getline(fin,String,'\n');
		numVars=atoi(String.c_str());
		varData varArr[numVars];		//create array to hold varData structs
		for (i=0;i<numVars;i++)			//set data to zero
			varArr[i].numParents=0;
				
		//read in variable names
		while(varsRead<numVars)
		{
			getline(fin,String);
			
			if(String.length()>1)		//skip over empth lines
			{
				cout<<"String is "<<String<<endl;
				iss << String;
				while(getline(iss,token,' '))
				{
					cout<<"Token is "<<token<<endl;
					varArr[varsRead].varName=token;
					cout<<"Token is "<<token<<" and varsRead is "<<varsRead<<endl;
					varsRead++;
				}
				iss.clear();
			}	
		}
		varsRead=0;


the output this is generating is:

1
2
3
4
5
6
7
8
9
10
11
String is Burglar Earthquake Alarm John Mary
Token is Burglar
Token is Burglar and varsRead is 0
Token is Earthquake
Token is Earthquake and varsRead is 1
Token is Alarm
Token is Alarm and varsRead is 2
Token is John
Token is John and varsRead is 3
Token is Mary
 and varsRead is 4


I cant explain the last 2 lines of output, I've got the token 'Mary' as its printed out in the second last line, then in my code i assign it to the struct variable then try to cout it again and its gone? its not even outputting the first half of the cout? how can that be?
The token 'Mary' is not being assigned to the struct either.
I'm guessing it has something to do with 'Mary' being the last token in the string because when i run the same thing on a file with a different number of variables, it always seems to lose the last one.

Any clues on this??
Please show how you have implemented the struct varData. Also, following statement is not correct:
 
varData varArr[numVars]; // numVars is a variable. Array size should be a constant 
you need to make sure that varsRead < numVars otherwise varsRead is out of bounds -> undefined behavior
abhishekm71,
This is the struct I'm using.

1
2
3
4
5
6
struct varData
{
	string varName;
	int numParents;
	vector <int> parents;
};


numVars is found after reading in the first line from the file, after this it will remain unchanged.
---------------------------------------------------
coder777
The file format is known, so i can be sure that it will exit the while loop when varsRead=numVars.
Last edited on
The behavior seems like there's a wild pointer somewhere and memory corruption, but I don't see anything in the code you provided that would cause this. Have you tried doing a clean followed by a build to make sure nothing is getting gunked up in the toolchain somewhere?


The following issues aren't likely to be causing your problem, but they deserve a quick comment or two

As Aabhishekm71 pointed out these lines:
1
2
		numVars=atoi(String.c_str());
		varData varArr[numVars];

are not legal C++. The size of an array must be a compile time constant in C++. GCC has a compiler extension enabled by default that allows it -- you may want to disable it.

Why do you need a numParents member in varData? Can't you just check the size of parents (parents.size()) if you need that info?

Why are you using stringstream here? Your file is completely space delimited which is what the extraction operator was made for. Using stringstream makes things a bit more complicated than they need to be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int main(int argc,char* argv[])
{
    if ( argc > 1 )
    {
        std::ifstream fin(argv[1]);

        unsigned nNames ;
        fin >> nNames ;

        std::vector<varData> data(nNames) ;

        unsigned nth = 0 ;
        while ( nth < nNames && fin >> data[nth++].varName )
            ;

        for ( unsigned i=0; i<data.size(); ++i )
            std::cout << data[i].varName << '\n' ;
    }
    else
        std::cerr << "Incorrect usage!  Supply a filename on the command line.\n" ;
}
instead of numVars, try using a literal constant like 5 for debugging purpose and check if the problem persists.
Thanks to both of you for your help, I've settled on another method that is working for me.
Topic archived. No new replies allowed.