void someFunction(){
char *buffer;
size_t bufsize = 32;
int bytes_read;
for (;;) {
buffer = (char *) malloc(bufsize * sizeof(char));
if (buffer == NULL) {
perror("Unable to allocate buffer");
exit(1);
}
FILE *ptr;
ptr = fopen("sample.txt", "a");
printf("Enter Stuff to write down:\n");
//getline(&buffer,&bufsize,stdin);
//fgets(buffer, 30, stdin);
//scanf("%[^\n]%*c", buffer);
//scanf("%s", buffer);
if (buffer[0] == '0') {
break;
}
WriteWithFprintf(ptr, buffer);
free(buffer);
fclose(ptr);
}
}
The problem is: if I use
getline(&buffer,&bufsize,stdin);
or
fgets(buffer, 30, stdin);
then it escapes the first like so:
Enter Stuff to write down:
Enter Stuff to write down:
0
If I use:
scanf("%[^\n]%*c", buffer);
then I get an infinite loop.
It does work with:
scanf("%s", buffer);
but I want input with space so this is not an option for me.
CodePudding user response:
All of the behaviors described for different variations on your code are consistent with the next character available to be read from stdin
being a newline, presumably from a preceding line of input.
In that case,
- the
getline()
andfgets()
alternatives will read the newline (and any preceding characters) as a line, and then loop to read the line you actually want on the second pass. - the first
scanf()
variation will read nothing on account of a matching failure for the%[^\n]
field (leading whitespace is not skipped for%[
directives). Not having matched anything to that, there will be no attempt to match anything to the%*c
. - the second
scanf()
alternative will work as you describe, becausescanf
will automatically consume leading whitespace when processing a%s
directive, including any newline.
There is a variety of things you could do, depending on exactly how want to handle input. Here is one:
int c = fgetc(stdin);
if (c == EOF) {
// handle eof ...
} else if (c != '\n') {
ungetc(c, stdin);
}
// your choice for reading the wanted data ...
That will consume up to one leading newline from stdin
to get it out of your way.
CodePudding user response:
getline and fgets failed to get input on first attempt
Neither failed. Both simply read a '\n'
and immediately returned. This '\n'
was left-over from a previous input function like scanf("%s", ...)
, that did not consume the entire line. getline()
is not part of the standard C library.
scanf("%[^\n]%*c", buffer);
fails to read anything when the first available character is '\n'
.
scanf("%s", buffer);
consumes all optional leading white space like '\n'
. This may appear to work for OP.
scanf("%[^\n]%*c", buffer);
and scanf("%s", buffer);
are both poor code as they do not have a width limit, risking buffer overflow.
I recommend for a learner to not use scanf()
at all and perform all input with fgets()
, including the part of code not posted.