How to flush an fstream?
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4

Thread: How to flush an fstream?

  1. #1
    Join Date
    Feb 2010
    Posts
    5

    How to flush an fstream?

    Hi.

    I'm not sure if flushing is the solution but, if it is, I don't know how to do it.
    Anyway, here's the problem:

    I'm creating a function to load information about textures from an ".mtl" file.
    The file has a few lines written for each texture, but I only need the name of the texture file, wich is written in a line that begins with an 'm'.
    Here's a sample file:

    Code:
    newmtl acmat_0
    Kd 1 1 1
    Ka 0.2 0.2 0.2
    Ks 0.2 0.2 0.2
    Ns 128
    Tr 0
    map_Kd T1_256.bmp
    So, I'm only interested on that "T1_256.bmp" string.
    To get it, my function opens the file, reads the first character of the line, and if it is'n an m i jumps to the other one until it finds an m. Then, it reads the line until the whitespace, and then reads the string.

    The problem is that, when it reaches the end, it seems to have an m still in the buffer, and it tries to read an inexistent string, giving me an OS error.

    Howerver, to look for the problem, I made a simpler function that only reads the first character, writes it on the screen, and, at the end, it says to me how many m's there were.
    Here's that function:

    Code:
    int ReadMTL ( char *FileName )
    {
    	char c;
    	char str[20];
    	int textures=0;
    
    	ifstream File(FileName, ios::in | ios::binary );
    	if(!File)
    	{
    		cout << "I didn't find the file " << FileName << "\n";
    		return 0;
    	}
    	cout << "File sucsessfully opened.  Counting textures...\n";
    	while(File)
    	{
    		File.get(c);
    		switch(c)
    		{
    		case 'm':
    			textures++;
    			cout << c << ": This is a texture!\n";
    			File.getline(str,20);
    			break;
    		default: 
    			cout << c << "\n";
    			File.getline(str,20);
    			break;
    		}
    		
    	}
    	cout << "Finished counting. There are "<< textures << " textures.\n";
    	File.close();
            return 1;
    }
    and here you can see the output:

    Code:
    File sucsessfully opened.  Counting textures...
    n
    K
    K
    K
    N
    T
    m: This is a texture!
    m: This is a texture!
    Finished counting. There are 2 textures.
    Obviously, there's an extra "texture" that souldn't be here, and it looks like it detects it because, when the stream reaches the EOF, it still makes a last loop without having updated the buffer. That's why I talked about flushing, althought there's no istream::flush function.

    Do you have any idea about how to avoid this?

    Thank you very much, and sorry for the long post!!!

  2. #2
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,565

    Re: How to flush an fstream?

    It would be easier to just read line by line and check the first character.
    If it is an 'm', put the line into a stringstream and parse it that way.

    Code:
        ifstream File(FileName );
    
        string line , fname;
    
        while (getline(File,line))
        {
            if (!line.empty() && line[0]=='m')
            {
                stringstream ss(line);		// include <sstream> for stringstream
                ss >> line >> fname;
                cout << "file = " << fname << "\n";
            }
        }

  3. #3
    Join Date
    Feb 2010
    Posts
    5

    Re: How to flush an fstream?

    Nice...
    I'll try it!

    Meanwhile, I found the solution of doing a "do {} while(file)", and using File.get(c), and File.unget(c) just before the lop end:

    [code]
    do{
    File.get(c);
    ...
    function code;
    ...
    File.get(c);
    File.unget();
    }while(File);

    But it's really a mess, and I'm not even sure of why does it works and why it didn't the other way.
    Anyway, thank you!

  4. #4
    Join Date
    Oct 2002
    Location
    Austria
    Posts
    1,284

    Re: How to flush an fstream?

    Code:
    	while(File) {
    this way the loop will still continue once after the last line was already read because EOF will only be set if a read operation fails.
    That's why you process the last line twice.
    Kurt

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center