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, becausescanfwill automatically consume leading whitespace when processing a%sdirective, 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.
