Understanding fgets and scanf in C

When learning C programming, one of the essential skills is mastering input functions. Two commonly used functions for reading input are fgets and scanf. Although they both read data, they have distinct behaviors and use cases. This blog will help beginners understand these differences clearly.

What is fgets?

The fgets function reads a string from a specified input stream and stores it in an array. Here’s the syntax for fgets:

char *fgets(char *str, int n, FILE *stream);
  • str: Pointer to the array where the read string will be stored.
  • n: Maximum number of characters to read (including the null terminator).
  • stream: Input stream to read from (e.g., stdin for standard input).

Key Points about fgets:

  1. Reads Until Newline or EOF: fgets reads up to n-1 characters, stopping at a newline character or the end-of-file (EOF).
  2. Handles Whitespace: It reads the entire line, including spaces, tabs, and other whitespace characters.
  3. Prevents Buffer Overflow: By specifying the maximum number of characters, it helps prevent buffer overflows.

Example of fgets:

#include <stdio.h>

int main() {
    char buffer[100];
    printf("Enter a string: ");
    if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
        printf("You entered: %s", buffer);
    }
    return 0;
}

What is scanf?

The scanf function reads formatted input from the standard input (stdin). Here’s the syntax for scanf:

int scanf(const char *format, ...);
  • format: A format string specifying how to interpret the input.
  • Additional arguments: Pointers to variables where the read data will be stored.

Key Points about scanf:

  1. Formatted Input: It reads input according to format specifiers (e.g., %d for integers, %s for strings).
  2. Stops at Whitespace: When reading strings with %s, it stops at the first whitespace character (space, tab, newline).
  3. No Automatic Newline Handling: It does not handle the newline character that might remain in the input buffer, which can cause issues in subsequent input operations.

Example of scanf:

#include <stdio.h>

int main() {
    char buffer[100];
    printf("Enter a string: ");
    scanf("%99s", buffer); // Note: Use a width specifier to avoid buffer overflow
    printf("You entered: %s\n", buffer);
    return 0;
}

Differences Between fgets and scanf

Understanding the differences between fgets and scanf can help you decide which function to use based on your needs. Here’s a comparison table to illustrate the differences:

Featurefgetsscanf
Reading ModeReads an entire lineReads formatted input
Stops ReadingAt newline or EOFAt whitespace (for %s)
Newline HandlingIncludes newline character in inputDoes not include newline (can cause issues)
Buffer Overflow ProtectionYes, by specifying maximum charactersProne to overflow unless width is specified
Whitespace HandlingReads all whitespace charactersStops at first whitespace (for %s)
Error HandlingReturns NULL on error or EOFReturns number of successfully read items

Let’s create a visual diagram to illustrate how data is stored using fgets and scanf, which will make it easier to understand the differences for beginners.

Diagram Explanation

  1. fgets: Reads an entire line including spaces and the newline character, stopping at the maximum specified characters or newline.
  2. scanf: Reads input based on format specifiers, stops at the first whitespace character (for %s), and does not include the newline character in the input.

Data Storage Diagram

Imagine the user inputs the string “Hello World” in both cases.

Using fgets:

Input: "Hello World\n"

Buffer (array) after `fgets(buffer, 100, stdin)`:
+---+---+---+---+---+---+---+---+---+---+---+----+
| H | e | l | l | o |   | W | o | r | l | d | \0 |
+---+---+---+---+---+---+---+---+---+---+---+----+

Using scanf:

Input: "Hello World\n"

Buffer (array) after `scanf("%s", buffer)`:
+---+---+---+---+---+----+
| H | e | l | l | o | \0 |
+---+---+---+---+---+----+

Remaining Input Stream: " World\n"

Visual Diagram

Let’s depict this in a simple ASCII-style diagram:

  Input: "Hello World\n"

  Using `fgets(buffer, 100, stdin)`:

  +---+---+---+---+---+---+---+---+---+---+---+----+
  | H | e | l | l | o |   | W | o | r | l | d | \0 |
  +---+---+---+---+---+---+---+---+---+---+---+----+

  Buffer contains: "Hello World"

  Using `scanf("%s", buffer)`:

  +---+---+---+---+---+----+
  | H | e | l | l | o | \0 |
  +---+---+---+---+---+----+

  Buffer contains: "Hello"

  Remaining Input Stream: " World\n"

Conclusion

  • fgets: Reads the entire line including spaces and newline, storing it all in the buffer. This is useful for reading whole lines of text.
  • scanf: Reads input up to the first whitespace, storing only the first word in the buffer. The remaining input is left in the input stream.

Understanding these differences will help you choose the appropriate function based on your needs. fgets is more versatile for reading lines of text, while scanf is useful for parsing formatted input.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top