Sign in to follow this  
Icebone1000

sscanf - how Im suppose to use it for that?

Recommended Posts

Im trying to do this: File_p.getline( Line, 1000 ); sscanf( Line, "%d %c %d %c %d %d %c %d %c %d %d %c %d %c %d", tmpF[0], eatslash, tmpF[1], eatslash, tmpF[2], tmpF[3], eatslash, tmpF[4], eatslash, tmpF[5], tmpF[6], eatslash, tmpF[7], eatslash, tmpF[8] ); Witch is equivalent of this( At least is what I understood about this func): //File_p>>tmpF[0]>>eatslash>>tmpF[1]>>eatslash>>tmpF[2]>>tmpF[3]>>eatslash>>tmpF[4]>>eatslash>>tmpF[5]>>tmpF[6]>>eatslash>>tmpF[7]>>eatslash>>tmpF[8];//get 9 indices But sscanf are puting werid values on my array, is the first time I use it and cant figure out whats going on. Thats what a line gets: 1/1/1 2/2/2 3/3/3 3/3/3 2/2/2 4/4/4 It is not getting neither the first value correctly.

Share this post


Link to post
Share on other sites
Nevermind, I just forgot to put '&' on the variables..

BTW I think is good to point that sscanf is a million times faster than '>>' as I guessed:

ms sscanf(release, x64):
56.254868
52.737598
54.236492
53.433758
53.610428

ms ifstream >>(release, x64)
95.837546
94.708611
93.654243
92.235176
93.818764



Share this post


Link to post
Share on other sites
If you are using "eatslash" just to ignore it (as it seems) sscanf has an interesting feature to parse something but just ignore it.

Check out the "%*" syntax, I use often for strings "%*s" and it should make parsing faster too. Let us know timings :)

Share this post


Link to post
Share on other sites
Two bits of advice:
1) Avoid std::istream::getline in favour of std::getline since the later function works with an std::string (avoiding raw char arrays with all the problems that produces).
2) Use std::istringstream rather than sscanf.

Share this post


Link to post
Share on other sites
ms sscanf with %*c(release, x64)
54.890099
54.492992
54.398979
52.433685
52.738811

Thats what I changed, much cleaner! but didnt change much the performance
sscanf( Line, " %d %*c %d %*c %d %d %*c %d %*c %d %d %*c %d %*c %d", &tmpF[0], &tmpF[1], &tmpF[2], &tmpF[3], &tmpF[4], &tmpF[5], &tmpF[6], &tmpF[7], &tmpF[8] );

Share this post


Link to post
Share on other sites
Im about to kill myself trying to figure out the best way to work with files, any advice you can give me will be so much appreciated that I will mary you..

The first thing I figured out is that Im better using windows api to open and read the file( since( as pointed on windows internals book) c++ routines at some point call those(createfile, read/writefile))

What I was thinkig was loading the entire file to an array( since is what readfile does) and work just on the array..in my mind I think this is problay the fastest(just a guess)...I didnt follow my own guess because I suck, I dont know any array/string manipulation funcs to give me the freedom I want to do stuff...so I went back to the fstream stuff witch I never really liked(witch I also dont know a damn, but at least am more used to...)

Im considering a few things now, using c++ string stuff, using c to manipulate array, or use my damn arms and create my own funcs to traversee the array and doing the stuff I will need( like finding new lines and stuff )

You can think anything, but damn, maya load these files on ridiculous blink of eyes, my code get on a situation that looks is stucked on a infinite loop, but actually is just still working, how they do that?? Lack of knowledge is killing me..

Whats the problem on using sscanf if its faster btw?



Actually Im not understanding a crazy situation(at debuging looks fine, everything works as suppose), my app start consumes all my ram(4GB)! also the mouse get slow, and I need to ctrl+alt+del to close it..and that happens loading a file of 229KB! Any idea why this happens? Is this because std::vectors are actually terrible and Im better making the damn wheel that everyone loves to flame...
-___- yes, Im desperate(and my english sucks)

Share this post


Link to post
Share on other sites
Quote:
Original post by Icebone1000

Whats the problem on using sscanf if its faster btw?



Actually Im not understanding a crazy situation(at debuging looks fine, everything works as suppose), my app start consumes all my ram(4GB)! also the mouse get slow, and I need to ctrl+alt+del to close it..and that happens loading a file of 229KB! Any idea why this happens? Is this because std::vectors are actually terrible and Im better making the damn wheel that everyone loves to flame...
-___- yes, Im desperate(and my english sucks)


i guess you answered your question yourself..

scanf is very old, very chaotic designed, and definitely not failsafe. tons of ways to use it in a wrong way resulting in memory bugs or crashes.

which is why you should use iostreams instead. and they could actually be faster. why?

iostreams know at COMPILE TIME what types they will read from the file. sscanf has to parse at RUNTIME the scan-string, interpret all the parameters, and based on this, read then those values.

so if done right, iostreams should dance around scanf in performance. and definitely in savety.

Share this post


Link to post
Share on other sites
But i just substituted all ifstream>> by sscanf and my performace power uped from 92.235176 to 39.570114 ms...how I suppose to do that little stuff of getting string from file and parsing on variables?

File_p.getline( Line, 1000 );
sscanf( Line, " %d %*c %d %*c %d %d %*c %d %*c %d %d %*c %d %*c %d", &tmpF[0], &tmpF[1], &tmpF[2], &tmpF[3], &tmpF[4], &tmpF[5], &tmpF[6], &tmpF[7], &tmpF[8] );

//File_p>>tmpF[0]>>eatslash>>tmpF[1]>>eatslash>>tmpF[2]>>tmpF[3]>>eatslash>>tmpF[4]>>eatslash>>tmpF[5]>>tmpF[6]>>eatslash>>tmpF[7]>>eatslash>>tmpF[8];//get 9 indices



Share this post


Link to post
Share on other sites
i'm not using c++ since years so i can't help you in detail (and especially not with pre-c dated libraries like sscanf). it would be easy to do in .net, though.. :)

and as long as you have your memory leaks, i would not consider the performance important. how much time is it worth spending to just actually getting it working? esp. as you have an already working solution.

maybe (just maybe) maya has an actual parser written to load the files. and that would be much faster even than sscanf.

if it's performance-important, use binary files tailored down to your needs (xna does this, at compilation of your game, it compiles the media data to the fitting binary versions with only the data one needs). that would be even faster than the actual parser that you could write.


but, as you can see, i can't really help you with the problem itself. i just would never touch a function that was written and designed way before any of the actual platforms you can develop on. it's very old (older than you maybe? older than me at least i guess). and as such, very very outdated.

it's unsave in a lot of ways (you have to manually match parsing type and the actual input type you give in / it can read beyond the input string resulting in errors, etc etc..).

i'd stay with the std input version.

Share this post


Link to post
Share on other sites
another idea could be to actually read the file like you do for sscanf (means the std::getline or what ever you use), and THEN use stringstream to read it in (so instead of ifstream>>bla>>bla>>bla, you'd use stringstream>>bla>>bla>>bla then).

maybe just the pattern in which the file gets accessed defines the performance (hdd's are very slow, which is why i moved to ssds over a year ago).

maybe try that out?



if i look at your original example, it actually looks like you're reading it all twice. first a getline, and then still from the same stream the actual inputting. instead of using the actual data you got from getline.

Share this post


Link to post
Share on other sites
as said, no c++ guru here anymore..

the simple way would be


std::ifstream input("filename");
float bla,bla2,bla3;

input>>bla>>bla2>>bla3;


no clue what your getline in there actually is for :)


the longer stringstream style way would be sort of like that


std::ifstream input("filename"); //could be a FILE*, too, or windows file reading routines
float bla,bla2,bla3;

std::string inputline;
std::getline(input, inputline);

std::istringstream reader(inputline);
reader>>bla>>bla2>>bla3;





all of the reading obviously in a loop.

Share this post


Link to post
Share on other sites
Im still to try the istringstream method, but just figure out something that will make you surprise .

ACTUALLY, the code that makes things loading forever and ever, consuming all my damn memory, is the first one I was using(fstream):

File_p>>tmpF[0]>>eatslash>>tmpF[1]>>eatslash>>tmpF[2]>>tmpF[3]>>eatslash>>tmpF[4]>>eatslash>>tmpF[5]>>tmpF[6]>>eatslash>>tmpF[7]>>eatslash>>tmpF[8];//get 9 indices

Just tried the 229KB file again using the sscanf, it loads normaly! How the hell do you explain that!

A code mistake? it happens just to this file, the cube and the teapot file loads ok.
With the sscanf every file is loading fine! Thats just unbeliveble!

Share this post


Link to post
Share on other sites
I dont want post the entire code because is homework..(not much smart post it all donne on the internet )

But here is the part that gives problem if made with ifstream(remember it just gives problem with some files...I cant understand that).

Also, I didnt get istringstream to work
"reader>>tmpF[0]>>eatslash>>tmpF[1]>>..." This dont work, weird values are filled( weird because it just dont work here with the INT[9] array and the chars to skip, because it works like that:
"reader>>tmpV[0]>>tmpV[1]>>tmpV[2]" ) Any tips?
-EDIT-:Works in the case where theres no char between the ints, didnt mean it works in that different way in the same situation.



Sorry the loads of info..To try make things more clear, here is what a line can have:(4 different lines)
1 2 3
17/57/49 18/58/50 19/60/51
5374//6046 5429//6101 5375//6047
1/1 2/2 3/3





INT tmpF[9];


//test
std::string inputline;
std::istringstream reader;

...

case 'f':{

File_p.getline( Line, 1000 );
sscanf_s( Line, " %d %*c %d %*c %d %d %*c %d %*c %d %d %*c %d %*c %d", &tmpF[0], &tmpF[1], &tmpF[2], &tmpF[3], &tmpF[4], &tmpF[5], &tmpF[6], &tmpF[7], &tmpF[8] );
//std::getline( File_p, inputline );//#1
//reader.str( inputline );//#2

//File_p>>tmpF[0]>>eatslash>>tmpF[1]>>eatslash>>tmpF[2]>>tmpF[3]>>eatslash>>tmpF[4]>>eatslash>>tmpF[5]>>tmpF[6]>>eatslash>>tmpF[7]>>eatslash>>tmpF[8];//get 9 indices//#1
//reader>>tmpF[0]>>eatslash>>tmpF[1]>>eatslash>>tmpF[2]>>tmpF[3]>>eatslash>>tmpF[4]>>eatslash>>tmpF[5]>>tmpF[6]>>eatslash>>tmpF[7]>>eatslash>>tmpF[8];//get 9 indices//#2
Vfaces.push_back(tmpF[0]);
Vfaces.push_back(tmpF[1]);
Vfaces.push_back(tmpF[2]);
Vfaces.push_back(tmpF[3]);
Vfaces.push_back(tmpF[4]);
Vfaces.push_back(tmpF[5]);
Vfaces.push_back(tmpF[6]);
Vfaces.push_back(tmpF[7]);
Vfaces.push_back(tmpF[8]);





sscanf_s is doing his job great, I think I finished it, I can load any type of obj( pos/tex/normal, pos, pos//normal, I dont have any pos/tex to test)..

Loading an obj of 10.4MB takes about 700ms ( o.o i think is faster than what maya takes, but maya probaly do a bunch of stuff before and after reading it ).

[Edited by - Icebone1000 on March 20, 2010 3:38:07 PM]

Share this post


Link to post
Share on other sites
I did some more tests if anyone are interested.

Final tests-Releases( .obj - 10.4MB )
x64
ascii - 2th
702.937500
676.418335
676.896118
682.726746
680.038574
677.672058
673.938110

unicode - 1th
704.785706
672.032349
679.355713
674.809692
671.088989
670.519714
677.948059


x32
ascii - 4th
858.969849
828.131531
828.041626
827.433777
836.886597
830.307129
836.410828

unicode - 3th
841.685486
824.360229
828.506775
824.891479
821.062622
824.294617
824.668579

Why is the difference so little between unicode and ascii? Isnt unicode 2 times more data to manage? And why unicode is faster?
---Edit---
My bad, I wasnt actually using any unicode on my read loop. Just substituted everything for tchar routines and types and substituted ifstream for wifstream..loading times for the same file is arround 9 seconds at first, and 3 seconds on consecutive trys...o.o"

[Edited by - Icebone1000 on March 20, 2010 6:12:33 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Icebone1000
BTW I think is good to point that sscanf is a million times faster than '>>'


1) That's not even twice as fast. :)

2) Try adding this line to the beginning of main() in your C++ test program:

std::ios_base::sync_with_stdio(false);

Share this post


Link to post
Share on other sites
I dont understand ifstream behavior man..now its skiping a line every time..
do{
File_p.getline( Line, 1000 );//Line have correct line

switch( Line[0] ){

case 'f':{
//File_p>> is using next line
File_p>>eatslash>>tmpF[0]>>eatslash>>tmpF[1]>>eatslash>>tmpF[2]>>tmpF[3]>>eatslash>>tmpF[4]>>eatslash>>tmpF[5]>>tmpF[6]>>eatslash>>tmpF[7]>>eatslash>>tmpF[8];//get 9 indices//#1
Vfaces.push_back(tmpF[0]);
Vfaces.push_back(tmpF[1]);
Vfaces.push_back(tmpF[2]);
...
break;
...

The only difference now is that File_p.getline is not on the same block of File_p>> as before:
do{

File_p.get(ch);//get next char

switch( ch ){
case 'f':
File_p.getline( Line, 1000 );

File_p>>tmpF[0]>>eatslash>>tmpF[1]...
...


... I give up on that thing

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this