Topic 36 of 100 Input and Output Functions Interactive Tutorial

Understanding gets() in C: Syntax, Behavior, and Legacy Usage

12 mins read Last updated: 22 Aug 2026 25,600 views
C Compiler 0.00%

What is Understanding gets() in C? Core Concept & Direct Summary

Core Objective & Problem Statement

Why was `gets()` permanently removed from the C11 standard, and why is `fgets()` the safe modern replacement?

Direct Answer Summary

If you've been following this tutorial series in order, you've already heard me warn about gets() a couple of times. Now it's time to look it straight in the eye.

gets() is one of the most infamous functions in the entire history of C. It reads a full line of text from the user — spaces and all — which sounds wonderfully convenient. And it was convenient... right up until the world discovered that it's fundamentally, unfixably unsafe. So unsafe, in fact, that the C standards committee took the extraordinary step of removing it from the language entirely in C11.

So why write a tutorial about a function you should never use? Three good reasons:

  1. You'll still encounter gets() in old code, old textbooks, and university courses
  2. Understanding why it's dangerous teaches you one of the most important lessons in all of programming
  3. Knowing its history makes you genuinely appreciate the safe alternative, fgets()

Let's dig in.

(Suggested image: a "warning sign" style graphic — the gets() function with a hazard border and the text "Removed in C11")


How Does Understanding gets() in C Work? In-Depth Mechanics & Architecture

What Was gets() Supposed to Do?

gets() — short for "get string" — was designed to read one complete line of input from stdin and store it in a character array.

Syntax (historical):

You pass it a character array, it reads everything the user types until they press Enter, stores it in the array (replacing the newline with a null terminator), and returns a pointer to the array.

How it was used back in the day:

main.c
Run Online
#include <stdio.h>
int main() {
    char name[50];
    printf("Enter your name: ");
    gets(name);
    // reads the FULL line, spaces included
    printf("Hello, %s!\n", name);
    return 0;
}

Sample Run:

main.c
Run Online
Enter your name: Priya SharmaHello, Priya Sharma!

And there's the original appeal: unlike scanf("%s", ...), which stops dead at the first space, gets() happily swallows "Priya Sharma" — first name, last name, everything. For reading sentences and full names, it felt like the obvious choice.

If that's all there was to the story, we'd all still be using it today. Unfortunately...


The Fatal Flaw: gets() Doesn't Know When to Stop

Look at that syntax again:

You hand gets() a pointer to your array. Notice what's missing from that? Any mention of how big the array is.

gets() has no idea whether you gave it room for 10 characters or 10,000. It just keeps reading and writing until it hits a newline — and if the user types more characters than your array can hold, gets() writes them right past the end of your array into memory that belongs to something else.

That has a name: a buffer overflow. And it's not a theoretical problem — it's one of the most exploited security vulnerabilities in computing history.

(Suggested image: THE key diagram for this page — a memory layout showing char name[10] as 10 boxes, then "user types 30 characters" overflowing into boxes labeled "other data" and "return address" turning red)

See it happen:

main.c
Run Online
#include <stdio.h>
int main() {
    char password[10];
    int access = 0;
    // 0 means locked out
    printf("Enter password: ");
    gets(password);
    printf("Access level: %d\n", access);
    return 0;
}

Type a short password, everything's fine. But type 30 characters, and the extra 20 spill past password... potentially landing right on top of access. Depending on how your compiler arranged memory, an attacker who knows this can literally overwrite program variables just by typing a long input. No hacking tools required — just a keyboard.

This exact class of bug has powered real-world attacks for decades, most famously the Morris Worm of 1988 — one of the internet's first major worms — which exploited a buffer overflow to spread across thousands of machines.


Why Couldn't They Just Fix It?

Here's the painful part: gets() cannot be fixed. It's not a buggy implementation — it's a broken design.

To read input safely, a function must know the size of the buffer it's writing into. But gets()'s signature has no size parameter, and changing the signature would break every program ever written with it. The flaw is baked into the API itself.

The C committee's journey with gets() tells the story:

YearStandardWhat Happened
1989C89/C90gets() standardized (dangerous from day one)
1999C99Officially deprecated — "don't use this"
2011C11Removed from the standard entirely
TodayGCC/ClangCompiling with it triggers warnings; modern glibc may refuse to link it

If you compile old code containing gets() today, you'll typically see something like:

main.c
Run Online
warning: the 'gets' function is dangerous and should not be used.

When your compiler literally prints the word "dangerous," it's worth listening.


The Safe Replacement: fgets()

Everything gets() did, fgets() does safely — because it asks the one question gets() never did: how much room do I have?

Syntax:

main.c
Run Online
char *fgets(char *str, int size, FILE *stream);
  • str — where to store the input
  • size — the maximum number of characters to read (including the null terminator)
  • stream — where to read from (stdin for keyboard input)

The same program, done right:

main.c
Run Online
#include <stdio.h>
int main() {
    char name[50];
    printf("Enter your name: ");
    fgets(name, sizeof(name), stdin);
    printf("Hello, %s", name);
    // no \n needed — see below    return 0;}

Now if the user types 500 characters, fgets() reads at most 49 and stops. The overflow simply can't happen. Full line? Check. Spaces? Check. Buffer respected? Finally, check.

(Suggested image: side-by-side code comparison — gets() version marked with red ✗, fgets() version marked with green ✓)

Two fgets() Quirks to Know

Quirk 1: It keeps the newline. If the user presses Enter, the \n gets stored in your string. Trim it like this:

main.c
Run Online
#include <string.h>
name[strcspn(name, "\n")] = '\0';

Quirk 2: Long input leaves leftovers in the buffer. If the user types more than fits, the excess stays in stdin and can confuse your next input call. Clear it the same way we learned in the getchar() tutorial:

main.c
Run Online
int c;
while ((c = getchar()) != '\n' && c != EOF);

gets() vs fgets() vs scanf("%s"): The Full Comparison

gets() ❌fgets() ✅scanf("%s") ⚠️
Reads spaces/full lineYesYesNo (stops at space)
Bounds checkingNoneYes (size parameter)Only with width limit: %49s
Keeps the newlineNo (replaces with \0)YesNo
Buffer overflow riskExtremeSafeRisky without width limit
Status in modern CRemoved (C11)Standard and recommendedStandard, use with care

The verdict is clear: for reading strings, fgets() is the modern, correct answer. And if you ever do use scanf("%s", ...), always give it a width limit one less than your array size — scanf("%49s", name) for char name[50] — leaving room for the null terminator.


What If You're Forced to Read Old gets() Code?

Legacy codebases, old university assignments, dusty textbooks — gets() still lurks in all of them. If you need to modernize such code, the conversion is almost always mechanical:

main.c
Run Online
// Old (dangerous):
gets(name);
// New (safe) — a drop-in replacement:
fgets(name, sizeof(name), stdin);
name[strcspn(name, "\n")] = '\0';
// match gets() behavior: strip newline

Two lines, and a 30-year-old security hole disappears. If you're ever maintaining old C code, hunting down every gets() call is one of the highest-value fixes you can make.


The Lessons gets() Teaches Every C Programmer

Even though you'll (hopefully) never call it, gets() leaves behind lessons worth keeping forever:

  1. Never trust input size. Users will always type more than you expect. Always.
  2. A function that writes to memory must know the buffer's limits. No exceptions.
  3. "It works in my tests" means nothing. Buffer overflows hide until someone types the "wrong" thing — and attackers specialize in typing the wrong thing.
  4. Language standards evolve for reasons. When a function gets removed from C itself, that's the industry's way of carving the warning in stone.
  5. The safe alternative usually costs you one extra argument. That's a cheap price for security.

(Suggested image: a "5 Lessons" graphic styled like a graduation certificate — playful take on "what gets() taught us")


Final Thoughts

gets() is a genuine piece of computing history: a function so dangerous that the C language — famous for trusting programmers with raw memory and loaded pointers — decided it was too reckless to keep. That's really saying something.

The takeaway is simple. Know what gets() was. Recognize it in old code. Never write it in new code. For every situation where you'd reach for it, fgets() does the same job with a seatbelt attached.

And honestly, that's the bigger story of learning C: the language hands you enormous power, and functions like gets() are the cautionary tales that teach you to respect it.

Runnable C Code Example & Practical Implementation

main.c
Run Online
#include <stdio.h>
#include <string.h>
int main() {
    char buffer[64];
    printf("Enter your full name: ");
    if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
        // Strip trailing newline character if present
        buffer[strcspn(buffer, "\
")] = '\\0';
        printf("Hello, %s! (Safely read with fgets)\
", buffer);
    }
    return 0;
}

Key Takeaways, Best Practices & Memory Safety Rules

Best Practice & Key Takeaways
NEVER use gets(). Always use fgets(buf, sizeof(buf), stdin) or POSIX getline() for reading lines of text safely.

Frequently Asked Questions & Technical Interview Insights

Technical Interview & Viva Questions

Frequently asked C programming interview questions
Q

Q: Why is `gets()` forbidden in modern C programming?

A: `gets()` has no buffer length parameter. It is impossible to prevent buffer overflows with `gets()`, making any program utilizing it inherently insecure.
Q

Q: Does `fgets()` guarantee null-termination?

A: Yes, `fgets()` always null-terminates the string as long as `num > 0` and no I/O error occurs.

Related Tools, Tutorials & Authoritative References

Recommended Interactive Tools

Authoritative Standards & Citations