Thread: Get a specific line from ifstream

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    169

    Get a specific line from ifstream

    Hiya

    I'm coding a parser for text files, and need some help figuring out why the stl is playing tricks on me.

    What I want:
    The parser will go through the text, line by line, and do some stuff.
    When a certain line is reached, I want to store its position so I can return to it later, and continue to parse from that position onwards.

    It's easy to do it by storing all the lines in a string vector, but I don't want to waste memory to hold the entire text file.

    So I read about tellg and seekg, and thought I will be good to go with the following code:

    the function:
    Code:
    void Parse(std::string Filename) {
    	std::ifstream f;
    
    	// Open the file for parsing.
    	f.open(Filename.c_str(), std::ifstream::in);
    	if (f.is_open()) {
    
    		std::string line;
    		std::streampos line_three = std::ios::beg;
    
    		// Read some lines from the file.
    		while (f.good()) {
    			std::streampos pos = f.tellg();
    			std::getline(f, line);
    			// Store the position of the line "hello world".
    			if (line == "hello world") {
    				line_three = pos;
    			}
    		}
    		f.clear();
    		f.seekg(line_three, std::ios::beg);
    		//f.seekg(-2, std::ios::cur);
    		std::getline(f, line);
    		std::cout << "Line#3: " << line << std::endl;
    
    		f.close();
    	}
    	return;
    }
    text.txt:
    Code:
    some text
    some more text...
    hello world
    finish!
    But instead of printing the third line, my output is:
    Code:
    llo world
    I must be doing something stupid, but I couldn't find out what exactly.

    Thanks

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    I've no idea - the code looks OK and it works here.
    Code:
    $ g++ foo.cpp
    $ ./a.out 
    Line#3: hello world
    $ gcc --version
    gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    May 2006
    Posts
    169
    Thanks for taking a look at this, Salem

    I used mingw to compile the code under Windows 7. The fact that it worked for you under ubuntu had me try something...
    I converted the text file format to unix instead of dos, it works OK.

    But I don't get it. Isn't stl supposed to be portable? How would I make my parser parse both unix and dos text files?

  4. #4
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    you could generate an index of the file using a std::vector<int> to store the beginning position of each line. you would still need to read through the whole file at least once, but then you'd have the ability to jump directly to whichever line you want.

  5. #5
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Try opening the file in binary mode. I'd bet the newlines are messing you up. There are 2 lines above where your "hello world" is and the output you show is 2 characters off.

    Your loop is also off due to your use of testing good (which is essentially a similar test to eof). You want to test the read op instead of using good. If your last line of the file was the one you are trying to find, it would report an incorrect position. Your loop should probably be something like this:
    Code:
    // Read some lines from the file.
    std::streampos pos = f.tellg();
    while (std::getline(f, line)) {
        // Store the position of the line "hello world".
        if (line == "hello world") {
            line_three = pos;
        }
        pos = f.tellg();
    }
    Last edited by hk_mp5kpdw; 06-05-2012 at 10:32 AM.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  6. #6
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by hk_mp5kpdw View Post
    Try opening the file in binary mode. I'd bet the newlines are messing you up.
    Wouldn't the newline related trouble increase in binary mode ?
    I mean, in stream/text mode, the differences between newline and newline+carriage-return across platforms are easily and automagically handled .
    (Or, it is supposed to be automatic, afaik....I do not have the experience of testing on multiple platforms and compilers.)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How do I back up a line with ifstream?
    By Programmer_P in forum C++ Programming
    Replies: 2
    Last Post: 04-20-2011, 01:50 PM
  2. Read A File From A Specific Line
    By dsured in forum C Programming
    Replies: 8
    Last Post: 03-16-2011, 08:56 PM
  3. deleting ifstream line
    By jed in forum C++ Programming
    Replies: 8
    Last Post: 10-26-2006, 02:55 PM
  4. Replies: 6
    Last Post: 04-28-2006, 12:06 PM
  5. Read SPECIFIC line from text file
    By 13373ar5 in forum C++ Programming
    Replies: 5
    Last Post: 05-21-2004, 05:14 AM