Reputation: 1038
My objective is to change the delimiter of scanf
to "\n
".
I tried using scanf("%[^\n]s",sen);
and works fine for single inputs.
But when i put the same line inside a for
loop for multiple sentences it gives me garbage values.
Does anyone know why?
Here's my code:
char sen[20];
for (i=0;i<2;i++)
{
scanf("%[^\n]s",sen);
printf("%s\n",sen);
}
Upvotes: 4
Views: 37270
Reputation: 59
While using scanf("%[^\n]", sen)
in a loop, the problem that occurs is that the \n
stays within the input buffer and is not flushed. As a result next time, when the same input syntax is used, it reads the \n
and considers it as a null input. A simple but effective solution to address this problem is to use:
char sen[20];
for (i=0;i<2;i++)
{
scanf("%[^\n]%*c",sen);
printf("%s\n",sen);
}
%*c
gets rid of the \n
character in the input buffer.
Upvotes: 1
Reputation: 349
I know I am late, but I ran into same problem after testing C after a long time.
The problem here is the new line is considered as input for next iteration.
So, here is my solution, use getchar()
to discard the newline the input stream:
char s[10][25];
int i;
for(i = 0; i < 10; i++){
printf("Enter string: ");
scanf("%s", s[i]);
getchar();
}
Hope it helps :)
Upvotes: 1
Reputation: 41
%[^\n]
leaves the newline in the buffer. %[^\n]%*c
eats the newline character.
In any case, %[^\n]
can read any number of characters and cause buffer overflow or worse.
I use the format string %*[^\n]%*c
to gobble the remainder of a line of input from a file. For example, one can read a number and discard the remainder of the line by %d%*[^\n]%*c
. This is useful if there is a comment or label following the number, or other data that is not needed.
Upvotes: 4
Reputation: 41
char sen[20];
for (i=0;i<2;i++)
{
scanf("%[^\n]s",sen);
printf("%s\n",sen);
getchar();
}
Hope this helps ... actually "\n" remains in stream input buffer... Ee need to flush it out before scanf is invoked again
Upvotes: 2
Reputation: 754480
Consider this (C99) code:
#include <stdio.h>
int main(void)
{
char buffer[256];
while (scanf("%255[^\n]", buffer) == 1)
printf("Found <<%s>>\n", buffer);
int c;
if ((c = getchar()) != EOF)
printf("Failed on character %d (%c)\n", c, c);
return(0);
}
When I run it and type in a string 'absolutely anything with spaces TABTABtabs galore!', it gives me:
Found <<absolutely anything with spaces tabs galore!>>
Failed on character 10 (
)
ASCII (UTF-8) 1010 is newline, of course.
Does this help you understand your problem?
It works in this case (for a single line) but if I want to take multiple lines of input into an array of arrays then it fails. And I don't get how
scanf
returns a value in your code?
There are reasons why many (most?) experienced C programmers avoid scanf()
and fscanf()
like the plague; they're too hard to get to work correctly. I'd recommend this alternative, using sscanf()
, which does not get the same execration that scanf()
and fscanf()
do.
#include <stdio.h>
int main(void)
{
char line[256];
char sen[256];
while (fgets(line, sizeof(line), stdin) != 0)
{
if (sscanf(line, "%255[^\n]", sen) != 1)
break;
printf("Found <<%s>>\n", sen);
}
int c;
if ((c = getchar()) != EOF)
printf("Failed on character %d (%c)\n", c, c);
return(0);
}
This reads the line of input (using fgets()
which ensures no buffer overflow (pretend that the gets()
function, if you've heard of it, melts your computer to a pool of metal and silicon), then uses sscanf()
to process that line. This deals with newlines, which are the downfall of the original code.
char sen[20];
for (i=0;i<2;i++)
{
scanf("%[^\n]s",sen);
printf("%s\n",sen);
}
Problems:
scanf()
succeeded.scanf()
The definition of scanf()
(from ISO/IEC 9899:1999) is:
§7.19.6.4 The scanf function
Synopsis
#include <stdio.h> int scanf(const char * restrict format, ...);
Description
2 The
scanf
function is equivalent tofscanf
with the argumentstdin
interposed before the arguments toscanf
.Returns
3 The
scanf
function returns the value of the macro EOF if an input failure occurs before any conversion. Otherwise, thescanf
function returns the number of input items assigned, which can be fewer than provided for, or even zero, in the event of an early matching failure.
Note that when the loop in my first program exits, it is because scanf()
returned 0, not EOF.
Upvotes: 17