Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sscanf doesn't move, scanning same integer everytime

I have a string that has ints and I'm trying to get all the ints into another array. When sscanf fails to find an int I want the loop to stop. So, I did the following:

int i;
int getout = 0;
for (i = 0; i < bsize && !getout; i++) {
    if (!sscanf(startbuffer, "%d", &startarray[i])) {
        getout = 1;
    }
}
//startbuffer is a string, startarray is an int array.

This results in having all the elements of startarray to be the first char in startbuffer. sscanf works fine but it doesn't move onto the next int it just stays at the first position.

Any idea what's wrong? Thanks.

like image 821
MinaHany Avatar asked May 31 '12 03:05

MinaHany


People also ask

Does sscanf move the pointer?

You are correct: sscanf indeed does not "move", because there is nothing to move. If you need to scan a bunch of ints, you can use strtol - it tells you how much it read, so you can feed the next pointer back to the function on the next iteration.

What happens if sscanf fails?

sscanf() Return valueIf a matching failure occurs before the first receiving argument was assigned, returns zero. If input failure occurs before the first receiving argument was assigned, EOF is returned.

Is sscanf thread safe?

The string-based functions, such as sprintf() and sscanf() , do not depend on the stdio library. These functions are thread-safe.


2 Answers

Convert the string to a stream, then you can use fscanf to get the integers. Try this. http://www.gnu.org/software/libc/manual/html_node/String-Streams.html

like image 50
waitingkuo Avatar answered Oct 08 '22 09:10

waitingkuo


The same string pointer is passed each time you call sscanf. If it were to "move" the input, it would have to move all the bytes of the string each time which would be slow for long strings. Furthermore, it would be moving the bytes that weren't scanned.

Instead, you need to implement this yourself by querying it for the number of bytes consumed and the number of values read. Use that information to adjust the pointers yourself.

int nums_now, bytes_now;
int bytes_consumed = 0, nums_read = 0;

while ( ( nums_now = 
        sscanf( string + bytes_consumed, "%d%n", arr + nums_read, & bytes_now )
        ) > 0 ) {
    bytes_consumed += bytes_now;
    nums_read += nums_now;
}
like image 35
Potatoswatter Avatar answered Oct 08 '22 10:10

Potatoswatter