Thread: fgets() vs gets()

  1. #1
    Registered User
    Join Date
    Jul 2007
    Location
    Texas
    Posts
    103

    fgets() vs gets()

    I know a lot of you guys say to use fgets() instead of gets(). But I am not quite sure why. Could someone tell me why people say to do that instead of just the fact that you won't accidentally input too many characters. Also if you use gets() and put that input into a variable, how could you do the equivalent of that using fgets.. w/o saving a different file everytime.. or is that the whole point to save a file..?

  2. #2
    Fear the Reaper...
    Join Date
    Aug 2005
    Location
    Toronto, Ontario, Canada
    Posts
    625
    Teacher: "You connect with Internet Explorer, but what is your browser? You know, Yahoo, Webcrawler...?" It's great to see the educational system moving in the right direction

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by alexnb185 View Post
    I know a lot of you guys say to use fgets() instead of gets(). But I am not quite sure why. Could someone tell me why people say to do that instead of just the fact that you won't accidentally input too many characters. Also if you use gets() and put that input into a variable, how could you do the equivalent of that using fgets.. w/o saving a different file everytime.. or is that the whole point to save a file..?
    Yeah... Because who cares if you input too many characters? Writing good software is overrated.

  4. #4
    Registered User
    Join Date
    Jul 2007
    Location
    Texas
    Posts
    103
    Uh, ok, that is why I made this whole thread was bc I wanted to know how to do it correctly.. wow.. and happy_reaper, I read that FAQ and it told me what I already know. It however had a link to another page that would tell me exactly what I need to know; but yay for me the page it linked to wasn't online anymore.. so... any other ideas or anything to help me out..

  5. #5
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Because gets() assumes the buffer you pass to it is large enough for any input,

    For example if you do:
    Code:
    char buf[10];
    gets(buf);
    If the user enters more than 9 characters, buf isn't going to be a string (no null-terminator), and if they enter more than 10 you'll get a segfault, gets will write past the end of buf (which could break other variables, and cause a segfault if you're lucky).

  6. #6
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    1. Undefined Behavior
      • corruption of data
      • security
      • crashes
      • freezes
      • bsods
      • core dumps
      • stack traces
      • lock-ups
    2. Your colleagues will yell at you

  7. #7
    Registered User
    Join Date
    Jul 2007
    Location
    Texas
    Posts
    103
    nono see I understand that.. I just don't understand how fgets() works.. .like when you use gets() you can imeddiatly print that string to the console, but with fgets you need a file, so I am asking how does it work if I wanted to get a string form the user.. but using fgets... is that possible to do?

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    As others have said, gets() assumes that the user is doing "nice things". One of the most common problems with computer programs not working correctly is "input validation".

    Input validation is that you check what the user has input - this can be several steps:
    1. The input is "not too big".
    2. The input doesn't contain invalid information (e.g. telephone numbers don't have letters in them).

    Further checks are of course necessary sometimes - checking that dates are "OK" means checking that the month is between 1 and 12 (or Jan .. Dec if month isn't numeric), day is within 1 and 31 (or 28, 29 or 30 depending on which month), etc, etc.

    ISBN's [book "id" numbers, found on the back of books newer than 1970 or so] should be checksum validated, so that the number is at least likely to be correct.

    Invalid input leads to all sorts of "bad things" - ranging from security vulnerabilities, crashes, infinite loops or just plain incorrect results.

    If you can get the C-library to do part of your input validation, such as making sure the data isn't too long, then that's something YOU don't have to write code for (and possibly get wrong?)

    Just saying "Don't input too many characters" is fine if you have users that don't make mistakes and that you trust - I know a few people I trust, fewer that doesn't make mistakes... (And I'm certainly NOT in the second bunch).

    fgets isn't hard to use - yes, it requires a few more arguments, but it's not hard. If you really still want to use gets(), you could actually fake it by using the following macro:

    #define gets(x) fgets(x, sizeof(x), stdin)

    Note that this doesn't work if you are using a different input type than a char array - e.g. if you use malloc()/new to get a chunk of memory to input your data into, sizeof doesn't work right.

    --
    Mats

  9. #9
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Code:
    char *fgets( char *str, int n, FILE *file );
    fgets does the same thing gets does but better, because you passed a length argument. It accesses it's file argument, grabs n characters, stores them in str and returns str, or NULL if there was an error or EOF was encountered.

    Saving files has nothing to do with it really.

    There was an example in the faq but I guess another doesn't hurt. For example
    Code:
    #include <stdio.h>
    
    int main( void ) {
      char line[1024];
    
      puts( "Enter some input and it will be echoed back." );
    
      while ( fgets( line, sizeof line, stdin ) )
        puts( line );
    
      /** What happened when fgets returned NULL ? **/
      if ( ferror( stdin ) )
        perror( "stdin" );
      else if ( feof( stdin ) )
        puts( "No more input - bye!" );
    
      return 0;
    }
    You'd only want to run this if you can redirect stdin or send EOF from your keyboard, or something.

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by alexnb185 View Post
    nono see I understand that.. I just don't understand how fgets() works.. .like when you use gets() you can imeddiatly print that string to the console, but with fgets you need a file, so I am asking how does it work if I wanted to get a string form the user.. but using fgets... is that possible to do?
    Use "stdin" as a file - just like gets() does - except gets does it implicitly, in fgets you have to explicitly say what file you want to get data from.

    --
    Mats

  11. #11
    Registered User
    Join Date
    Jul 2007
    Location
    Texas
    Posts
    103
    thanks citizen I pretty much get it now :]... and mat you are always a big help, thanks to you too

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. fgets not working after fgetc
    By 1978Corvette in forum C Programming
    Replies: 3
    Last Post: 01-22-2006, 06:33 PM
  2. problem with fgets
    By learninC in forum C Programming
    Replies: 3
    Last Post: 05-19-2005, 08:10 AM
  3. problem with fgets
    By Smoot in forum C Programming
    Replies: 4
    Last Post: 12-07-2003, 03:35 AM
  4. fgets crashing my program
    By EvBladeRunnervE in forum C++ Programming
    Replies: 7
    Last Post: 08-11-2003, 12:08 PM
  5. help with fgets
    By Unregistered in forum C Programming
    Replies: 2
    Last Post: 10-17-2001, 08:18 PM