# sscanf - how Im suppose to use it for that?

This topic is 2853 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## 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 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 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 on other sites
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 on other sites
Since you're using C++, you shouldn't be using sscanf, as others have said.

Personally, I'd rather someone repeatedly jumped on my balls than made me use sscanf.

##### 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 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 on other sites
You can do like that too:

sscanf(line, "%d/%d/%d %d/%d/%d %d/%d/%d", &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5], &tmp[6], &tmp[7], &tmp[8]);

##### Share on other sites
"string-to-int and int-to-string benchmarks."

Reinventors of the wheel FTW

##### Share on other sites
"
You can do like that too:

sscanf(line, "%d/%d/%d %d/%d/%d %d/%d/%d", &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5], &tmp[6], &tmp[7], &tmp[8]);
"

That doesnt work for me.

##### Share on other sites
Quote:
 Original post by Icebone1000Whats 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)

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 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 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 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 on other sites
How do I get a line from ifstream to an istringstream?
std::istringstream ssLine;

std::getline( File_p, ssLine );

I get all confused with all that string, iostream, sstream mess..

##### 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 routinesfloat 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 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.

##### Share on other sites
Everytime I set the string I have to istringstream.str(string) or is a permanent association ?

##### Share on other sites
please show the whole file loading from the moment you open the file to the point where it crashes.

##### Share on other sites
void std::istringstream::str(std::string const&) copies the contents of the argument into the internals of the istringstream.
Thus, it's fine if the argument goes out of scope, it can even be a temporary.

##### 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:
-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 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 on other sites
Quote:
 Original post by Icebone1000BTW 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 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 on other sites

This topic is 2853 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.