Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C, what is a safe alternative to sscanf?

Tags:

c

I found online that in C++ there's an alternative, but what about plain-old C? I appreciate any tips or advice.

like image 706
Caffeinated Avatar asked Feb 12 '12 01:02

Caffeinated


People also ask

What can I use instead of sscanf?

If you need more powerful tools for more complex parsing, then you could consider Regex or even Spirit from Boost.

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.

What is alternative of scanf in C?

There is no alternative for the scanf() in C language but there are some functions which can replace some of its functionality. They are gets() and getch(). But please note that the scanf() can read a wide range of values of different data types.


2 Answers

It depends on what you want to do with it.

Since you have the string in memory, you can safely avoid buffer overflows by being careful about the arguments you pass. For example, if you're scanning into a string, using "%s", just use a target buffer big enough to hold the biggest string that could possibly be there (and make sure that the source buffer is a valid string, i.e., that it's '\0'-terminated).

One danger of all the *scanf() functions is that if you're scanning a numeric value, and the input value is too big to be represented in the target type, the behavior is undefined. For example, this program:

#include <stdio.h>
int main(void) {
    const char *s = "999999999999999999999999999";
    int n;
    sscanf(s, "%d", &n);
    printf("n = %d\n", n);
    return 0;
}

has undefined behavior (unless INT_MAX is really really big).

You can safely scan numeric values using the strto*() functions: strtol(), strtoll(), strtoul(), strtoull(), strtof(), strtod(), strtold(). Their behavior on errors is a bit tricky, but at least it's well defined.

like image 130
Keith Thompson Avatar answered Sep 18 '22 00:09

Keith Thompson


I believe you're looking for the "m" modifier. It dynamically allocates memory to hold the extracted string, so as to avoid buffer overflows. The only drawback is that it's a GNU extension, so e.g. MSVC probably won't recognize it.

Here is an existing Stack Overflow answer on that topic.

Here's an example of how to use it:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
    char *str;
    printf("Enter your name:\n");
    scanf("%ms", &str);

    printf("Hello %s!\n", str);
    free(str);
    return 0;
}
like image 39
ulatekh Avatar answered Sep 18 '22 00:09

ulatekh