-
February 6th, 2010, 06:14 AM
#1
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!!!
-
February 6th, 2010, 10:01 AM
#2
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";
}
}
-
February 10th, 2010, 03:51 PM
#3
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!
-
February 10th, 2010, 04:18 PM
#4
Re: How to flush an fstream?
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|