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

แชร์
ฝัง
  • เผยแพร่เมื่อ 22 ต.ค. 2024

ความคิดเห็น • 43

  • @emirhandemir3872
    @emirhandemir3872 2 ปีที่แล้ว +21

    Great explanation

  • @AhmadAlMutawa_abunoor
    @AhmadAlMutawa_abunoor ปีที่แล้ว +2

    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.

    • @PortfolioCourses
      @PortfolioCourses  ปีที่แล้ว +1

      Hi Ahmad, this video covers how to clear the standard input buffer: th-cam.com/video/N7-MueK2CX8/w-d-xo.html. :-)

  • @Brock-Landers
    @Brock-Landers 2 ปีที่แล้ว +7

    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, '
    ') == NULL)
    while((fgetc(stdin) != '
    ');
    For input from a file also check for end of file or you will go into an infinite loop :
    if(strchr(buffer, '
    ') == NULL)
    {
    char discard;
    while((discard = fgetc(fp) != '
    ' && discard != EOF);
    }
    Then strip the newline character, only if one exists:
    buffer[strcspn(buffer, "
    ")] = '\0';
    Now buffer contains exactly what one would expect.

    • @PortfolioCourses
      @PortfolioCourses  2 ปีที่แล้ว +2

      Thanks for sharing this! 🙂

    • @edgarherrera8587
      @edgarherrera8587 2 ปีที่แล้ว +1

      Hi Brock. Do you have a code (i.e. at GitHub) where I can see your solution implemented? I have been looking for a solution since days ago. But this might bring me some light. Thanks

    • @Brock-Landers
      @Brock-Landers 2 ปีที่แล้ว

      @@edgarherrera8587 Here's a video I made on the subject that uses this exact code:
      th-cam.com/video/ITR-Acel7tg/w-d-xo.html
      There is a link in the description to the source code on my github for that channel.

    • @cervelex
      @cervelex ปีที่แล้ว

      @@Brock-Landers nice

  • @bettyswunghole3310
    @bettyswunghole3310 4 หลายเดือนก่อน

    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?

  • @sabitnirob983
    @sabitnirob983 ปีที่แล้ว +2

    Thanks for this class.. ❤️👍

  • @py4311
    @py4311 8 หลายเดือนก่อน

    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.

  • @vicsteiner
    @vicsteiner 3 หลายเดือนก่อน

    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.

  • @mateuscruz3009
    @mateuscruz3009 11 หลายเดือนก่อน +1

    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?

  • @vicsteiner
    @vicsteiner 3 หลายเดือนก่อน

    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?

  • @Stekaren
    @Stekaren 9 หลายเดือนก่อน

    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

    • @swati9841
      @swati9841 5 หลายเดือนก่อน

      we can use the fgets function only if we know the size of the string so instead of using fgets its better to use selective scanf syntax:-scanf("%[^
      ]", str); in this syntax ^ indicates starting of string and
      indicates the end of the line and str is string name

  • @sai_eshu7159
    @sai_eshu7159 ปีที่แล้ว +1

    great explanation....

  • @Stekaren
    @Stekaren 9 หลายเดือนก่อน

    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:
    "); //
    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?

  • @gourabmaityeducation
    @gourabmaityeducation ปีที่แล้ว

    Thank you so much 😊😊

  • @fadyasaad1105
    @fadyasaad1105 ปีที่แล้ว +1

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

    • @PortfolioCourses
      @PortfolioCourses  ปีที่แล้ว

      Great question Fady! :-) This video might help you out: th-cam.com/video/0UJX96_ZpVE/w-d-xo.html. These answers might help too: stackoverflow.com/q/7898215.

  • @elmarc4289
    @elmarc4289 ปีที่แล้ว

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

  • @Architector120
    @Architector120 2 ปีที่แล้ว +2

    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
    #include
    void my_event(clock_t *cnt, int time_delay)
    {
    if(clock() - *cnt >= time_delay)
    {
    *cnt = clock();
    printf("%ld
    ", clock());
    }
    }
    int main()
    {
    clock_t tim = 0;
    while(1)
    {
    my_event(&tim, 1000);
    if(tim == 10000) break;
    }
    return 0;
    }

    • @PortfolioCourses
      @PortfolioCourses  2 ปีที่แล้ว +2

      I'm not too sure, I think it depends on what you mean by non-blocking delay and what you're trying to do. Is the goal to delay executing some code by some amount of time, but to allow other code to execute in the meantime? If that's the case, it sounds like a situation best solved using threads. These folks have an interesting article on the idea: learn.digilentinc.com/Documents/407. And others seem to suggest using threads to solve the problem: stackoverflow.com/questions/7771142/non-blocking-sleep-timer-in-c. Maybe I can make a video about this, though I think I'd likely solve the problem using threads. :-)

    • @Architector120
      @Architector120 2 ปีที่แล้ว

      I already thought about using threads... But here's the catch... CPU single threaded...

    • @PortfolioCourses
      @PortfolioCourses  2 ปีที่แล้ว +1

      @@Architector120 Interesting, that makes things more challenging. 🙂
      I think if the delay is for some amount of time, the general idea would be something like this:
      time1 = the current time
      do {
      // do work that can be done now
      time2 = the current time
      diff = difference between time2 and time1
      } while (diff < desired);
      // do work that could only be done after diff amount of time has passed
      Just out of curiosity, what is the work that needs to be done in-between waiting some amount of time? Is it something that can be put into a function and called frequently? Is the delay for some fixed amount of time like 10 seconds, or is it until some event has occurred? Maybe I can make a video on this idea some day.

  • @luka_9196
    @luka_9196 11 หลายเดือนก่อน

    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.

    • @henry_tsai
      @henry_tsai 7 หลายเดือนก่อน

      The second fgets isn't needed if you just want to avoid overflow from the first input, fgets already limits how many characters it's going to read.
      However, I assume you want to read user input for the second time and the remaining characters in the stdin stream may wrongly be read in. In which case, a solution I come up with is to: 1.check if the user's first input is longer then first input buffer and has thus remaining data in stdin stream 2. if so, clear stdin stream 3. read user input.
      For step1, since fgets will stop reading if a
      is encountered, you can check if the first input string contains a
      , ex: with buffer size 5 and user inputs "abc
      ", then you knows there isn't any excess characters in stdin, then you can use a "if" to skip step2 and use another fgets() to read second input. if first input doesn't contain
      , then it means user input more character then the buffer size, ex: buffer size 5 but user inputs "abcdef
      ", then in buffer will be "abcd\0", and "ef
      " will remain in stdin, then you can use:
      char c[2];
      while(c[0] != '
      '){
      fgets(c, 2, stdin);
      }
      which should clear out any remain characters in stdin, then you can continue to step3 and use another fgets() to read.

    • @haroldcruz8550
      @haroldcruz8550 6 หลายเดือนก่อน

      That's actually considered the best practice specially for newbies

  • @josso8584
    @josso8584 ปีที่แล้ว

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

    • @PortfolioCourses
      @PortfolioCourses  ปีที่แล้ว

      That's awesome! :-) I hope one day TH-cam does AI translation on the fly. Hopefully this translation makes sense.

  • @mimicmian
    @mimicmian 11 หลายเดือนก่อน

    謝謝!

    • @PortfolioCourses
      @PortfolioCourses  11 หลายเดือนก่อน

      And wow again thank you so much! :-D

  • @Bolvarsdad
    @Bolvarsdad ปีที่แล้ว +3

    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
    size_t get_line(char *buffer, size_t bufsz)
    {
    size_t buflen = 0;
    int ch;
    while ((ch = getchar()) != EOF && ch != '
    ')
    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
    ", (int)nread, buffer);
    return 0;
    }
    Input: 12345678
    Output: 12345

    • @PortfolioCourses
      @PortfolioCourses  ปีที่แล้ว

      Thank you for sharing this! :-)

    • @IonizedComa
      @IonizedComa ปีที่แล้ว

      I always just use scanf("%[^
      ]s", stringName);

    • @PortfolioCourses
      @PortfolioCourses  ปีที่แล้ว

      @@IonizedComa that works! 🙂

    • @Queue_27
      @Queue_27 ปีที่แล้ว

      to me, getchar is the only one that make sense out of everything. i always feel safe considering every char even \0 and
      .

  • @Awwe12675
    @Awwe12675 ปีที่แล้ว

    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

    • @PortfolioCourses
      @PortfolioCourses  ปีที่แล้ว +3

      Yes, the actual term "stdin" is a macro in C. If anyone wants to learn more about that you can read up on it here: man7.org/linux/man-pages/man3/stdin.3.html. The standard input stream is a bigger concept than just a macro that sets to 1 though. It's not even necessarily going to be user input, it could be a file if it is re-directed when the programmer is run. Maybe one day I can make a video on the standard input streams and re-directing them. :-)