What is the difference between scanf("%s")
, scanf(”%[^\n]s")
and gets(a)
in C programming?
scanf("%[^\n]s", a)
scanf("%s", a)
gets(a)
What is the main difference between the three ways of taking character array input?
What is the difference between scanf("%s")
, scanf(”%[^\n]s")
and gets(a)
in C programming?
scanf("%[^\n]s", a)
scanf("%s", a)
gets(a)
What is the main difference between the three ways of taking character array input?
scanf("%s",a);
will skip over leading whitespace characters in the input, and will match characters until a whitespace character is encountered (or until end-of-file is reached), storing them in the array indicated by the argument. Note that this is susceptible to buffer overflow, so it is best to include a width specifer that provides a maximum number of characters to read from the input. For example, if a
is an array of 100 char
s, %99s
should be used; this leaves space for the \0
terminator that is automatically added by scanf()
.
Neither scanf("%s[^\n]",a);
nor scanf("%[^\n]s", a);
is probably what was meant, and instead this should be: scanf("%[^\n]",a);
. The %[]
is a scanset directive. There is no need to follow the %[]
directive with an s
, which would only tell scanf()
to match a literal s
in the input after finishing with %[]
. The scanset directive matches characters described within the brackets and assigns them to the corresponding argument. When a match fails, that character is placed back in the input stream. Here, the ^\n
indicates that all characters except for newline characters should be matched, so this directive will match characters until a newline is encountered, and the newline will remain in the input stream. The same advice about specifying a maximum width applies here as well: %99[^\n]
to avoid buffer overflow, if a
is an array of 100 char
s. Note that the %[^\n]
directive will match any character that is not a \n
, including other whitespace characters. This means that it will not skip over leading whitespace characters (but a leading \n
in the input will cause the directive to immediately fail, without making an assignment), in contrast to %s
, and will read lines of input containing spaces.
puts(a);
does not read input, but is an output function. Note that this function prints a newline after printing its argument. Perhaps you meant to include gets()
in this list of methods to gather input.
gets(a);
is an unsafe function that was deprecated in C99, and completely removed from the language in C11. You should never use this function for any reason. This function fetches a line of input, reading characters until a newline character is encountered, or until end-of-file is reached. The newline character is discarded; it is not stored in the array indicated by a
, and it is not returned to the input stream. For this reason, when gets()
was used in the past, it worked well with puts()
, which automatically prints a newline character after printing its argument.
Finally, for a little more information, there is fgets()
. This function fetches a line of input, but takes a size argument so that buffer overflow may be avoided. Given my earlier example of char a[100];
, fgets()
would be called like this:
fgets(a, 100, stdin);
or sometimes:
fgets(a, sizeof a, stdin);
Here, fgets()
reads at most one character less than the number specified by the size argument, allowing space for a \0
, which is always added. If the \n
is read, it is stored in a
. Since the newline is not discarded, puts()
does not work as well here; often the newline needs to be removed after taking input with fgets()
.
First of all, they all have undefined behavior for the same reason: They will read a number of characters you can't know in advance, but through your pointer, you provide storage where to store this data, and this storage has some fixed size. Therefore, there are always inputs possible that will overflow your buffer. You should'nt ever use any of these lines in your code.
That said:
gets()
reads a line of input and stores it to your buffer. It also reads the newline character, but this isn't stored. This function is broken by design, as there is no way to use it safely. Don't ever use it. It has been removed from the C standard in C11, so you could only use it with older standards anyways. The correct replacement is char a[100]; fgets(a, sizeof a, stdin);
. This will store the newline character in the buffer, though.
scanf("%[^\n]s", ...)
will also read a line of input. The []
conversion specifier takes a list of accepted or, with ^
in front, rejected characters. So with this syntax, it will accept any character except newline. Therefore, the newline character won't be read this way. The s
would be searched in the input literally, it's not what you mean. s
and []
are different conversion specifiers. To use this one correctly, you must use the field with like so: char a[100]; scanf("%99[^\n]", a);
. Note that you have to specify one less than your buffer size because scanf()
doesn't count the '\0'
character that's appended as an end mark for the string.
scanf("%s", ...)
reads a "word", that is it stops at the first whitespace character. To use this correctly, as above, use something like char a[100]; scanf("%99s", a);
.