My main problem here is that I have two strings and a float to read. The strings' size is 10 bytes, but I should be able to read no matter what input it is and store it inside the strings.
For example:
if my input is Hello world!
then the string should be string = "Hello wor"
if my input is Hello
then the string should be string = "Hello"
Now you might think this is obvious, just use fgets right? But that presents buffer problems when reading a second string. The thing is, I did find a fix, but that involves using the fflush function, but it appears that it doesn't work in a few compilers.
I searched for an alternative and found while ( getchar() != '\n')
but it actually doesn't work like fflush.
So what I'm asking here is there's a better alternative to read a string no matter the length of the input? This is what I came up with:
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv) {
char nom[10] , prenom[10];
double salaire;
fgets( nom , sizeof( nom ) , stdin );
nom[ strcspn( nom , "\n") ] = 0;
fflush(stdin);
fgets( prenom , sizeof( prenom ) ,stdin );
prenom[ strcspn( prenom , "\n") ] = 0;
fflush(stdin);
scanf("%lf",&salaire);
printf("%s\n",nom);
printf("%s\n",prenom);
printf("%lf\n",salaire);
return 0;
}
In this case, it's actually useful that fgets
includes '\n'
when reading input. If \n
is there at the end of the string, it means that fgets
was able to read the whole line till the end. If it's some other character, it means that fgets
stopped before reaching the end of the line and the whole line was not read. We can use this to use the getchar()
loop to clear stdin
only if the whole line has not been read.
#include <stdio.h>
#include <string.h>
int main(void)
{
char str1[10], str2[10];
fgets(str1, sizeof str1, stdin);
if (str1[strlen(str1) - 1] != '\n')
for (int c; (c = getchar()) != '\n' && c != EOF;);
fgets(str2, sizeof str2, stdin);
if (str1[strlen(str1) - 1] != '\n')
for (int c; (c = getchar()) != '\n' && c != EOF;);
// Now it's safe to remove the \n
str1[strcspn(str1, "\n")] = '\0';
str2[strcspn(str2, "\n")] = '\0';
printf("%s\n%s\n", str1, str2);
}
You can even make a simple wrapper around fgets
that does this whenever you read a line:
char *readln_and_clear(char *buf, size_t bufsz, FILE *stream)
{
if (fgets(buf, bufsz, stream) == NULL)
return NULL;
if (buf[strlen(buf) - 1] != '\n')
for (int c; (c = fgetc(stream)) != '\n' && c != EOF;);
// If you want
buf[strcspn(buf, "\n")] = '\0';
return buf;
}