0
0
CComparisonBeginner · 4 min read

Scanf vs gets vs fgets in C: Key Differences and Usage

In C, scanf reads formatted input but can leave newline characters in the buffer, gets reads a line but is unsafe and deprecated, while fgets safely reads a line with buffer size control and includes the newline character. Use fgets for safer input handling over gets and scanf when reading strings.
⚖️

Quick Comparison

Here is a quick comparison of scanf, gets, and fgets based on key factors.

Featurescanfgetsfgets
Input TypeFormatted input (e.g., %s, %d)String input (line)String input (line)
Buffer Overflow ProtectionNo (can overflow if not limited)No (unsafe, deprecated)Yes (limits input size)
Reads Newline CharacterNo (stops at whitespace)No (newline discarded)Yes (newline included if fits)
SafetyModerate (needs format control)Unsafe (deprecated)Safe (recommended)
Use CaseReading formatted dataLegacy line inputSafe line input with size limit
⚖️

Key Differences

scanf reads input according to a format specifier, such as %s for strings or %d for integers. It stops reading strings at the first whitespace and does not consume the newline character, which can cause issues for subsequent input calls.

gets reads an entire line until a newline but does not check the buffer size, making it unsafe and deprecated because it can cause buffer overflows and security risks.

fgets reads a line from a stream safely by specifying the maximum number of characters to read, including the newline character if it fits. It prevents buffer overflow and is the recommended way to read strings line-by-line in modern C programming.

⚖️

Code Comparison

Example reading a string input using scanf:

c
#include <stdio.h>

int main() {
    char name[20];
    printf("Enter your name: ");
    scanf("%19s", name);  // limit input to avoid overflow
    printf("Hello, %s!\n", name);
    return 0;
}
Output
Enter your name: Alice Hello, Alice!
↔️

fgets Equivalent

Example reading a string input using fgets safely:

c
#include <stdio.h>
#include <string.h>

int main() {
    char name[20];
    printf("Enter your name: ");
    if (fgets(name, sizeof(name), stdin)) {
        // Remove newline if present
        size_t len = strlen(name);
        if (len > 0 && name[len - 1] == '\n') {
            name[len - 1] = '\0';
        }
        printf("Hello, %s!\n", name);
    }
    return 0;
}
Output
Enter your name: Alice Hello, Alice!
🎯

When to Use Which

Choose scanf when you need to read formatted input like numbers or strings without spaces and you can control the format carefully. Avoid it for reading full lines because it stops at whitespace and leaves newlines in the buffer.

Never use gets because it is unsafe and removed from modern C standards.

Use fgets when you want to read a full line safely, especially strings that may contain spaces, and want to avoid buffer overflow risks. It is the safest and most reliable choice for line input.

Key Takeaways

Never use gets because it is unsafe and deprecated.
Use fgets to safely read lines with buffer size control.
Use scanf for formatted input but beware of leftover newlines.
fgets includes the newline character; remove it if not needed.
Always limit input size to prevent buffer overflow.