开发者

Why istream::getline() returns so many times (with nothing)

开发者 https://www.devze.com 2023-04-03 02:18 出处:网络
I am trying to read a poorly formatted text file, and maybe I\'m going about this the wrong way, but based on the getline documentation it sounded like it would pull values until the values weren\'t a

I am trying to read a poorly formatted text file, and maybe I'm going about this the wrong way, but based on the getline documentation it sounded like it would pull values until the values weren't a delimiter value (' ', in my case):

"If the delimiter is found, it is extracted and discarded, i.e. it is not stored and the next input operation will begin after it. If you don't want this character to be extracted, you can use member get instead."

But for some reason it returns nothing many times. See lines 604-607, all those commas in my output are returns of getline. Could someone tell me why it is returning blanks 6 times before it comes to the value? The text file only contains one space before the value. Thanks in advance. :)

Relevant screenshot: http://j.drhu.me/2011-09-07_1317.png

#include <iostream>
#include <fstream>
#include <string>
void CMuscleModel::LoadOpParams()
{
int i, j;

ifstream param("params.txt", ios::in);
        if (param.is_open())
        {
            stringstream iss, isn;
            string line, word;

            i=0; j=0;
            while (getline(param,line))
            {
                isn.clear();
                isn << line;
                if(i>27){
                    while (getline(isn,word,' ')) {
                        //LGma[i][j]=atof(word.c_str());
                        if(word == "SM"){
                            getline(param,line);
                            cout << line << endl << endl;

                            isn.clear(); isn << line;

                            getline(isn,word,' ');

                            int junk=0;
                            while (atof(word.c_str())==0){
                                junk++;
                                getline(isn,word,' ');
                            }

                            cout << atof(word.c_str()) << ", " << junk << endl;
                        }
                        if(word == "ST"){
                            cout << word << endl;
                        }
                        if(word == "BFL"){
                            cout << word << endl;
                        }
                        if(word == "BFS"){
                            cout << word << endl;
                        }
                        if(word == "MG"){
                            cout << word << endl;
                        }
                        if(word == "LG"){
                            cout << word << endl;
                        }
                        if(word == "RF"){
                            cout << word << endl;
                        }
                        if(word == "VM"){
                            cout << word << endl;
                        }
    开发者_如何学Python                    if(word == "VL"){
                            cout << word << endl;
                        }
                        if(word == "VI"){
                            cout << word << endl;
                        }
                        j++;
                    }
                }
                j=0; i++;
                isn.clear();
            }
        }
        param.close();
}

Ah, sorry for not including code.


If you're using space as a delimiter anytime it's encountered getline will return with whatever there was upto the delimiter. If the file had 5 spaces in a row before any other characters for example you'd now have to call getline 6 times.

Perhaps use the default newline character instead '\n'?

Edit: Didn't see code before. Perhaps restructure your code to read lines and then use find in conjunction with substr on each line to search for your keywords? Would be simpler code and less looping. There is no reason to read from the file only to output to a stringstream which you then read from.


Bi-directional I/O with std::stringstream is really ambiguous. I recommand that you use it a little differently.

ifstream param("params.txt", ios::in);
if (param.is_open())
{
    stringstream iss;
    string line, word;
    i=0; j=0;
    while (getline(param,line))
    {
        istringstream isn(line);
        // ...
    }
}

This creates a fresh string stream with clean state and contains the contents of the line read from the file each time. If you really want to re-use the instance for reading tokens on multiple lines, I recommand you use the .str(line) syntax rather than .clear() and operator<<.

If you want to clear the whitespace at the beginning of each line, you can use the std::ws manipulator:

istringstream isn(line);
isn >> ws;
// ...


I think the output text file I was reading from had trailing spaces and they were just being put into the stream so I was really confused about what was going on. I simply used .str("") at the end of each line to reset my current stream and things worked out marvelously. Thanks for all the help guys.

0

精彩评论

暂无评论...
验证码 换一张
取 消