Search code examples
ciouser-inputgetsputs

What is the difference between getchar/putchar, gets/puts and fgets/fputs (in C)?


I am currently studying input and output in C and I have found out that there are about a billion different ways to get input, such as, getch, getchar, gets and fgets, and the same with output (putchar, puts, fputs, etc.).

All these different methods of I/O are confusing me quite a bit, so I came on here to ask what the basic differences between the aforementioned functions are.

I also wrote a bit of code using these different functions and I commented in how I think they work, based on what I've learnt, but I'm not sure if my understanding is correct. I've read up on them in other places as well, but the explanations are very complicated and don't seem coherent.

So could anyone please tell me if I am using them correctly and if not, how I should use them and what are the main differences between them?

Here is my code:

#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>

void individualCharacters()
{
    char theChar;

    while ((theChar = getchar()) != '~') {  //    getchar() stores all characters in a line buffer as it is entered until newline is entered
        putchar(theChar);    // putchar() prints the characters in the line buffer and does not print a newline, line buffering depends on compiler
    }
}

void withoutF()
{
    char name[50];

    printf("What is your name? ");

    gets(name);    // receives a string until newline is entered, newline is then replaced with string terminator, array limit should not be passed

    puts("Hi");    // only prints one string at a time and adds the newline because gets() previously replaces the newline
    puts(name);
}

void withF()
{
    char name[50];

    printf("What is your name? ");

    fgets(name, 50, stdin);    // does add a newline so the newline takes up one space in the array, it stores input until either newline is entered or array limit is reached

    fputs("Hi ", stdout);    // does not print a newline but prints the string input up to the array limit
    fputs(name, stdout);
}

void main()
{
    //sum();

    //individualCharacters();

    //withoutF();

    //withF();

    //printRandomString();
}

These are just some functions I wrote that get input and display output in different ways, but I'm having trouble understanding why there are so many different ways of doing so.

If I have made any mistakes using the I/O functions, feel free to tell me so I can make amendments.

Thank you


Solution

  • fgets - reads up to SIZE-1 characters from a specified stream into a buffer, including the trailing newline if there's room. Adds a 0 terminator to the end of the buffer, making it a valid C string:

    char buffer[SIZE];
    
    if ( fgets( buffer, sizeof buffer, stdin ) ) // read from standard input
      do_something_with( buffer );
    else
      error();
    

    On success, fgets returns the address of the input buffer. On failure or end-of-file, it returns NULL.

    fgetc - reads a single character from the specified input stream and returns it:

    FILE *input_stream = fopen( "some_file", "r" );
    int c;
    while ( (c = fgetc( input_stream )) != EOF )
      do_something_with( c );
    

    gets - was deprecated after C99, removed completely from C2011. Like fgets, it would read a sequence of characters from standard input into a buffer and add a 0 terminator, but unlike fgets it did not provide a mechanism to limit input, making it a popular malware exploit. Also, it would not store a trailing newline to the buffer. Using it was guaranteed to introduce a point of failure in your code. Pretend you've never heard of it.

    getc - identical to fgetc, except that it may be implemented as a macro.

    getchar - reads a single character from standard input:

    int c;
    ...
    while( (c = getchar()) != EOF )
      do_something_with( c );
    

    fputs - writes a string to the specified output stream:

    char str[SIZE];
    ...
    fputs( str, output_stream ); 
    

    fputc - writes a single character to the specified output stream:

    while ( i < strsize )
      fputc( str[i], output_stream );
    

    putc - identical to fputc, except that it may be implemented as a macro

    putchar - writes a single character to standard output.