Why We Should Never Use gets()... And Why To Use fgets() Instead | C Programming Tutorial

preview_player
Показать описание
Рекомендации по теме
Комментарии
Автор

My 2 pennies, you can just discard the overflow up to newline so your next call will be clean.

For input from stdin:
if(strchr(buffer, '\n') == NULL)
while((fgetc(stdin) != '\n');


For input from a file also check for end of file or you will go into an infinite loop :
if(strchr(buffer, '\n') == NULL)
{
char discard;
while((discard = fgetc(fp) != '\n' && discard != EOF);
}

Then strip the newline character, only if one exists:
buffer[strcspn(buffer, "\n")] = '\0';

Now buffer contains exactly what one would expect.

Brock-Landers
Автор

This video is very informative. I wish you would include a way to flush the stdin before reading any left over from the previous attempt. That would have been wonderful.

AhmadAlMutawa_abunoor
Автор

Thank you! This is a very good explanation!

Can you just clarify one point, though? if I use "fgets(buffer, 5, stdin)" and then display the buffer contents, it shows four characters, but it's *_really_* showing 5 because the last character is the \0 Null character?

bettyswunghole
Автор

When you use the second fgets in the end of video, shouldn't have another space for data input in terminal? One for fgets buffer and other for fgets next? You only typed and entered one time, one data, why it happened?

mateuscruz
Автор

What if I want to discard any extra chars in the stdin and actually prompt the user again? How do we clean the stdin? Or how do I know how many times I have to call fgets till the stdin is empty and ready to read new input data from the user?

vicsteiner
Автор

Afaik, most of time, we would get more spaces than how much we have applied due to memory alignment for performance. but why 16 bytes[a-p] when you applied for 5, I think it would be 8.

py
Автор

Using gcc in Ubuntu when I tried passing the string with more than 5 chars like in the example it does print the abcdef string to the stdout but also the message:

*** stack smashing detected ***: terminated
Aborted (core dumped)

And the program return value was 134.

vicsteiner
Автор

i tried something like this
int main(){
char a[] = "hello"; // here im initializing my char array with a string without declaring how many characters i want in the array, i know that the compiler will put 6 characters away so that the char array a may store 5 characters + null characters = 6 characters.
printf("enter string:\n"); //
fgets(a, 21, stdin); /* here i use fgets, and i have 21 characters i want to write, which are "you are most welcome" 20 characters + white space character + the null character at the end that indicates end of the string = 21 characters total */
printf("string: %s", a); // will print "you are most welcome"

return 0;
}
i got no warning writing this. So still the question remains, do i need to dynamically allocate memory like you did sir or is this legal in C?

Stekaren
Автор

hello sir im trying to learn c on my own. so why i came here from neso academy was because of this: video was about difference between scanf and gets, in order to print out the white space character. what i understood was when the scanf() function sees a white space character it does not print anything else past that, so if i write "you are most welcome" it will only print out "you" and ignore the rest. with gets() the problem was as you are also mentioning, it can overwrite in the memory and use memory that is not allocated for the char array.

so in order to get the white space character and print out the complete sentence "you are most welcome" i can use fgets() function instead of gets(). my question is sir, do i need to dynamically allocate memory everytime with the malloc function or can i just go ahead and use fgets? im new to this and i appreciate any help you can give me

Stekaren
Автор

Muchas gracias amigo, de verdad que me has ayudado mucho. Saludos desde México

elmarc
Автор

Hi sorry I’m new to programming but if i use a second fgets to prevent overflow and the user doesn’t write a string longer than the max characters I chose the fgets want an input how do I resolve this issue thank you for the help.

luka_
Автор

Is there a way to clear stdin before fgets again??

fadyasaad
Автор

Can you explain how to make non-blocking delay or events in while loop in C? i came up with this approach... it works but CPU 100% loaded... hope you get the idea...

#include <stdio.h>
#include <time.h>

void my_event(clock_t *cnt, int time_delay)
{
if(clock() - *cnt >= time_delay)
{
*cnt = clock();
printf("%ld\n", clock());
}
}

int main()
{
clock_t tim = 0;
while(1)
{
my_event(&tim, 1000);
if(tim == 10000) break;

}
return 0;
}

Architector
Автор

Soy de Mexico y tuve que ver tu video en subtitulos pero tienes mi like jeje

josso
Автор

He bro stdin Is macro
stdin is 1 stdout is 0
Like that
#define stdin 1
#define stdout 0
stdin only to tell for programmer hey we need use input with fgets function

Awwe
Автор

Here's the function I always use to take input, which I afterwards use other accompanying functions to convert the string value to what I need.
#include <stdio.h>

size_t get_line(char *buffer, size_t bufsz)
{
size_t buflen = 0;
int ch;

while ((ch = getchar()) != EOF && ch != '\n')
if (buflen < bufsz)
buffer[buflen++] = ch;

return buflen;
}

int main(int argc, char **argv)
{
char buffer[5];
size_t nread = get_line(buffer, 5);

// I don't need to null terminate the buffer because of this printf format
// If you were using puts instead of printf here, you should null terminate it by writing:
// buffer[nread] = '\0';
// But since we're using printf in this case that can be ignored.
printf("%.*s\n", (int)nread, buffer);

return 0;
}

Input: 12345678
Output: 12345

Bolvarsdad