Hello all. I'm almost certain this question has been posted before, but I couldn't find it--I apologize if it's a repeat.

Anyway, I'm having a peculiar problem using getline when reading to a file. I know exactly how the file will be formatted, except the presence of comments at the end of a line is optional. Therefore I use a getline to grab the whole line out of the file, then read to my arrays what I need and dump the rest. The problem is that if a line ends immediately after a number I need to input (i.e. '27\n' instead of '27 \n') without a space or other character, the NEXT getline pulls in all zeros. So my input file looks like

10 20 5 !test comment
0 1 2
5 5 5 5 5 5 5 5 5 5
et cetera

So long as line 2 ends with a comment or a space, getline reads in the file just fine. However, if not, my 10 element array that should be filled with 5s is filled with zeros. A part of the code is below. I know it's a little obtuse, but I need to be able to handle 5.0*10 instead of 10 5s. I haven't implemented that yet but this is in preparation for that.

std::fstream infile(this->meshfile.c_str(),std::ios::in);
        if (infile.fail()) {
            std::cout << "Mesh file I/O error." << std::endl;
            return 1;
        }

        infile.getline(commentBuffer,bufsize);
        temp = commentBuffer;
        std::istringstream in(temp.c_str(),std::ios::in);
        in >> this->nx;
        in >> this->ny;
        in >> this->nz;

        //Get origin
        infile.getline(commentBuffer,bufsize);
        temp = commentBuffer;
        in.str(temp);
        //std::istringstream in(temp.c_str(),std::ios::in);
        for (ii=0;ii<=2;ii++) {
            in >> this->meshorigin(ii);
        }

        this->meshdx.resize(this->nx);
        this->meshdy.resize(this->ny);
        this->meshdz.resize(this->nz);
        this->nmod = nx*ny*nz;

        infile.getline(commentBuffer,bufsize);
                temp = commentBuffer;
        std::cout << temp << std::endl;
        in.str(temp);
        ii=0;
        while (ii <= nx-1) {
            in >> this->meshdx(ii);
            ii++;
        }

        infile.getline(commentBuffer,bufsize);
        temp = commentBuffer;
        in.str(temp);
        ii=0;
        while (ii <= ny-1) {
            in >> this->meshdy(ii);
            ii++;
        }

        infile.getline(commentBuffer,bufsize);
        temp = commentBuffer;
        in.str(temp);
        ii=0;
        while (ii <= nz-1) {
            in >> this->meshdz(ii);
            ii++;
        }

I should note that getline is reading the correct string. If I output temp it is filled with the proper numbers. However, the >> operator is failing. Why would it do this if the string wasn't input with a space at the end? Doing

temp += " \n";

didn't work either.

Thanks in advance for the help. Sorry for the long post--I was trying to be comprehensive.

Cheers!
Andy

Member Avatar for iamthwee

Still didn't get it.

It's because I'm not a posting expert! :p

Member Avatar for iamthwee

Stop trying to flirt with me. . .

Make your example simpler. . .

Forget the code, tell us your input and how you want it.

OK, sorry. The idea is that I'll have a file with very specific formatting. However there could be comments. The first line tells me how many elements will be in the 3rd, 4th, and 5th lines. So an input file might look like this:

3 2 5 !comment
0 0 0 !don't worry about this line
1.2 7.0 8.0
4 2
2.0*5

Note that on line 5 I can write 2.0* 5 instead of 2.0 2.0 2.0 2.0 2.0 (this format of file was originally written for a fortran program which understood implicitly what that meant).

All I want to do is read in the numbers, pop them into appropriate variables or arrays, and parse out the comments.

The specific issue that I'm having is that the code posted above works great so long as the last character in the input string is not part of a number I want to keep. If the last character IS part of a number I want to keep (i.e. the '0' of '8.0 in the 3rd line), then the next line is read in as all zeros (the array elements are 0 0 instead of 4 2).

Hope this is a little more illuminating. Thanks!

Heh, I've been accused of many things in my life, but flirtatious hasn't been one of them.

Stop trying to flirt with me. . .

Make your example simpler. . .

Forget the code, tell us your input and how you want it.

Member Avatar for iamthwee

Strip out the comments first, I assume every comment is prefixed by an exclamation mark as per your example right. . . Should be a piece of cake??

Strip out the comments first, I assume every comment is prefixed by an exclamation mark as per your example right. . . Should be a piece of cake??

The comments aren't really the problem. The only complication they make is that they preclude me from easily just looping over the number of elements I have in my file and inputting them directly into the variables using fstream. That's why I just use getline to get the whole line, then load up my variables directly using >> from istringstream. I could cut off the input using ! as the delimiter in getline, but that isn't getting at the problem I'm having (at least I don't see how it would change anything, since the problem occurs on lines that don't have comments).

@choragos ...
Check out the strtok function.... I think that might solve your problem....

@choragos ...
Check out the strtok function.... I think that might solve your problem....

I may take that route, but I still would like to understand what is wrong with my code. Why is using the istringstream >> operator failing to properly read in the string (which is full or the correct information) when the line read into the string using getline did not end with a space?

Is there some kind of close or flush operation with istringstream? I couldn't find one in the documentation...

I may take that route, but I still would like to understand what is wrong with my code. Why is using the istringstream >> operator failing to properly read in the string (which is full or the correct information) when the line read into the string using getline did not end with a space?

Is there some kind of close or flush operation with istringstream? I couldn't find one in the documentation...

After much trial and error, I DO need to flush the istringstream buffer. If I make a new istringstream object (in, in2, in3, etc) for each string I parse, it works. Any thoughts on why that is?

You have to clear() your stream.
When the line ends with the last number, a corresponding extract hits the end of string, and the stream is in end-of-file condition. Calling str() does not clear it.

You have to clear() your stream.
When the line ends with the last number, a corresponding extract hits the end of string, and the stream is in end-of-file condition. Calling str() does not clear it.

Great, thanks!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.