I have snprintf and it can avoid a buffer overflow, but why there is no function called snscanf?
Code:
int main()
{
ch
There's no need for an snscanf() because there's no writing to the first buffer argument. The buffer length in snprintf() specifies the size of the buffer where the writing goes to:
char buffer[256];
snprintf(buffer, sizeof(buffer), "%s:%d", s, n);
The buffer in the corresponding position for sscanf() is a null-terminated string; there's no need for an explicit length as you aren't going to write to it (it's a const char * restrict buffer in C99 and C11).
char buffer[256];
char string[100];
int n;
if (sscanf(buffer, "%s %d", string, &n) != 2)
...oops...
In the output, you are already expected to specify the length of the strings (though you're probably in the majority if you use %s rather than %99s or whatever is strictly appropriate):
if (sscanf(buffer, "%99s %d", string, &n) != 2)
...oops...
It would be nice/useful if you could use %*s as you can with snprintf(), but you can't — in sscanf(), the * means 'do not assign scanned value', not the length. Note that you wouldn't write snscanf(src, sizeof(buf1), "%s", buf1), not least because you can have multiple %s conversion specifications in a single call. Writing snscanf(src, sizeof(buf1), sizeof(buf2), "%s %s", buf1, buf2) makes no sense, not least because it leaves an insoluble problem in parsing the varargs list. It would be nice to have a notation such as snscanf(src, "%@s %@s", sizeof(buf1), buf1, sizeof(buf2), buf2) to obviate the need to specify the field size (minus one) in the format string. Unfortunately, you can't do that with sscanf() et al now.
Annex K of ISO/IEC 9899:2011 (previously TR24731) provides sscanf_s(), which does take lengths for character strings, and which might be used as:
if (sscanf_s(buffer, "%s %d", string, sizeof(string), &n) != 2)
...oops...
(Thanks to R.. for reminding me of this theoretical option — theoretically because only Microsoft has implemented the 'safe' functions, and they did not implement them exactly as the standard requires.)
Note that §K.3.3 Common definitions says: '... The type is rsize_t which is the type size_t.385)' (and footnote 385 says: 'See the description of the RSIZE_MAX macro in ' That means that in fact you can pass size_t without needing a cast — as long as the value passed is within the range defined by RSIZE_MAX in . (The general intention is that RSIZE_MAX is a largish number but smaller than SIZE_MAX. For more details, read the 2011 standard, or get TR 24731 from the Open Standards web site.)