The first thing you need to know before I explain your issue is that %[^\n]
will fail if the first character to be read is a \n
.
Now lets analyze what scanf("%*[^\n]%10[^\n]ms", string);
means:
%*[^\n]
scans everything until a newline character, but doesn't scan in the final \n
.
%10[^\n]ms
doesn't really do what you think it does:
- Remember!
%s
and %[
are two different format specifiers! The trailing s
is not part of the %[
specifier.
- You got the
m
at the wrong position.
Correcting these, it should be %10m[^\n]
which scans everything until a newline character or a maximum of 10 characters, whichever happens first, and also allocates enough memory to hold this string.
Another bug is that m
expects a char**
, not a char*
and so, you should be supplying &string
and not just string
.
Now, lets execute your scanf
(after correcting the above mistakes)!
- Execution reaches the
scanf
and scanf
waits for input.
- You type
123\n
.
%*[^\n]
scans and discards the 123
, sees the \n
, and stops scanning, not consuming the \n
.
%10m[^\n]
sees the \n
and fails for the reason given in the first sentence of my answer.
scanf
returns 0 (since nothing was scanned and assigned successfully) and scanf
completes execution.
printf
prints (null)
since string
is still NULL
.
Ok, so we now saw what went wrong. The real question is, why do you have %*[^\n]
at the start of scanf
for this small program? Remove it and everything will work as expected!
Suggestions:
- Add
scanf("%*[^\n]"); getchar();
after the scanf
so that the rest of the input (if any) along with the final \n
gets popped out of the stdin
and future reads will not be problematic.
- Check the return value of
scanf
to see if it was successful or not. RTFM to know what it returns.
Fixed code (Untested)
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *string = NULL;
printf("Type anything : ");
if(scanf("%10m[^\n]", &string) != 1)
{
fputs("Uh, oh! `scanf` failed! Exiting...\n", stderr);
return EXIT_FAILURE;
}
scanf("%*[^\n]");
getchar();
printf("Your input : %s\n", string);
free(string);
return EXIT_SUCCESS;
}
This answer assumes that your implementation supports the m
format specifier