Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get number of characters read by sscanf?

I'm parsing a string (a char*) and I'm using sscanf to parse numbers from the string into doubles, like so:

// char* expression; double value = 0; sscanf(expression, "%lf", &value); 

This works great, but I would then like to continue parsing the string through conventional means. I need to know how many characters have been parsed by sscanf so that I may resume my manual parsing from the new offset.

Obviously, the easiest way would be to somehow calculate the number of characters that sscanf parses, but if there's no simple way to do that, I am open to alternative double parsing options. However, I'm currently using sscanf because it's fast, simple, and readable. Either way, I just need a way to evaluate the double and continue parsing after it.

like image 427
Alexis King Avatar asked Nov 21 '12 22:11

Alexis King


People also ask

What does sscanf return in C?

The sscanf() function returns the number of fields that were successfully converted and assigned. The return value does not include fields that were read but not assigned. The return value is EOF when the end of the string is encountered before anything is converted.

What is the function of sscanf ()?

The sscanf() function reads data from buffer into the locations that are given by argument-list . Each argument must be a pointer to a variable with a type that corresponds to a type specifier in the format-string . The sscanf() function returns the number of fields that were successfully converted and assigned.

What is the difference between scanf () and sscanf () functions?

The scanf function reads data from standard input stream stdin into the locations given by each entry in the argument list. The argument list, if it exists, follows the format string. The sscanf function reads data from buffer into the locations given by argument list.

How do I use Fgets and sscanf?

If you use fgets() + sscanf() , you must enter both values on the same line, whereas fscanf() on stdin (or equivalently, scanf() ) will read them off different lines if it doesn't find the second value on the first line you entered.


2 Answers

You can use the format specifier %n and provide an additional int * argument to sscanf():

int pos; sscanf(expression, "%lf%n", &value, &pos); 

Description for format specifier n from the C99 standard:

No input is consumed. The corresponding argument shall be a pointer to signed integer into which is to be written the number of characters read from the input stream so far by this call to the fscanf function. Execution of a %n directive does not increment the assignment count returned at the completion of execution of the fscanf function. No argument is converted, but one is consumed. If the conversion specification includes an assignment suppressing character or a field width, the behavior is undefined.

Always check the return value of sscanf() to ensure that assignments were made, and subsequent code does not mistakenly process variables whose values were unchanged:

/* Number of assignments made is returned,    which in this case must be 1. */ if (1 == sscanf(expression, "%lf%n", &value, &pos)) {     /* Use 'value' and 'pos'. */ } 
like image 195
hmjd Avatar answered Oct 26 '22 07:10

hmjd


int i, j, k; char s[20];  if (sscanf(somevar, "%d %19s %d%n", &i, s, &j, &k) != 3)     ...something went wrong... 

The variable k contains the character count up to the point where the end of the integer stored in j was scanned.

Note that the %n is not counted in the successful conversions. You can use %n several times in the format string if you need to.

like image 28
Jonathan Leffler Avatar answered Oct 26 '22 07:10

Jonathan Leffler