I found online that in C++ there's an alternative, but what about plain-old C? I appreciate any tips or advice.
-
2Unlike a few standard functions in C, `sscanf` can be used safely. As doing pretty much anything in C requires care you might need to be more specific about your particular use case to get "safer" solutions to whatever problem you are considering. – CB Bailey Feb 12 '12 at 01:43
-
Hmm, so sscanf is safer than ... ? – Caffeinated Feb 12 '12 at 01:45
-
1Safe in what respect? Do you have a particular use-case with which you are concerned? – johnsyweb Feb 12 '12 at 01:53
-
Well just security-wise, safer against hackers I guess. Maybe it's safe enough then . BTW This is part of an assignment, and I googled to no avail so I said lemma try SO – Caffeinated Feb 12 '12 at 01:55
3 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.

- 254,901
- 44
- 429
- 631
-
1Good answer. I'll add that instead of `%s` which can overrun your buffer, I'd strongly recommend always explicitly setting the buffer size: `char buf[50]; sscanf(unknownString, "%49s", buf);` This truncates (and null-terminates) too-long strings, but protects memory. – Jonathan Lidbeck Aug 16 '18 at 16:27
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;
}
-
the OP is asking about plain-old-C, so probably not an extension like that. There's also `%as` in POSIX – phuclv Apr 25 '17 at 04:46
-
I believe `char *str = NULL` is better. Otherwise, extremely painful to handle various error conditions (EOF, IO Error, parsing errors). – dash-o Dec 04 '19 at 19:55
-
Under Windows, you can use sscanf_s
(see https://msdn.microsoft.com/en-us/library/t6z7bya3.aspx) which require you to provide the buffer length for every %s
match as an argument right after the buffer argument.
For example, sscanf_s( tokenstring, "%s", s, (unsigned)_countof(s) );
.

- 349
- 1
- 5
- 10