How to use sscanf in loops?

Andrew H. Hunter picture Andrew H. Hunter · Oct 20, 2010 · Viewed 17.3k times · Source

Is there a good way to loop over a string with sscanf?

Let's say I have a string that looks like this:

char line[] = "100 185 400 11 1000";

and I'd like to print the sum. What I'd really like to write is this:

int n, sum = 0;
while (1 == sscanf(line, " %d", &n)) {
  sum += n;
  line += <number of bytes consumed by sscanf>
}

but there's no clean way to get that information out of sscanf. If it returned the number of bytes consumed, that'd be useful. In cases like this, one can just use strtok, but it'd be nice to be able to write something similar to what you can do from stdin:

int n, sum = 0;
while (1 == scanf(" %d", &n)) {
  sum += n;
  // stdin is transparently advanced by scanf call
}

Is there a simple solution I'm forgetting?

Answer

Jonathan Leffler picture Jonathan Leffler · Oct 20, 2010

Look up the %n conversion specifier for sscanf() and family. It gives you the information you need.

#include <stdio.h>

int main(void)
{
    char line[] = "100 185 400 11 1000";
    char *data = line;
    int offset;
    int n;
    int sum = 0;

    while (sscanf(data, " %d%n", &n, &offset) == 1)
    {
        sum += n;
        data += offset;
        printf("read: %5d; sum = %5d; offset = %5d\n", n, sum, offset);
    }

    printf("sum = %d\n", sum);
    return 0;
}

Changed 'line' to 'data' because you can't increment the name of an array.