char *gets(char *str);Understanding gets() in C: Syntax, Behavior, and Legacy Usage
What is Understanding gets() in C? Core Concept & Direct Summary
Why was `gets()` permanently removed from the C11 standard, and why is `fgets()` the safe modern replacement?
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:
- You'll still encounter
gets()in old code, old textbooks, and university courses - Understanding why it's dangerous teaches you one of the most important lessons in all of programming
- 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:
Sample Run:
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:
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:
If you compile old code containing gets() today, you'll typically see something like:
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:
str— where to store the inputsize— the maximum number of characters to read (including the null terminator)stream— where to read from (stdinfor keyboard input)
The same program, done right:
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:
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:
gets() vs fgets() vs scanf("%s"): The Full Comparison
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:
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:
- Never trust input size. Users will always type more than you expect. Always.
- A function that writes to memory must know the buffer's limits. No exceptions.
- "It works in my tests" means nothing. Buffer overflows hide until someone types the "wrong" thing — and attackers specialize in typing the wrong thing.
- 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.
- 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
#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
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 questionsQ: Why is `gets()` forbidden in modern C programming?
Q: Does `fgets()` guarantee null-termination?
Related Tools, Tutorials & Authoritative References
Recommended Interactive Tools
- Online C Compiler & Runner — Interactive online GCC sandbox to execute C code in real time.
- Online C Code Editor & IDE — Multi-file C programming environment with code formatting.
- C++ Programming Tutorial — Transition from procedural C to Object-Oriented C++ with STL.
- JavaScript Programming Tutorial — Master modern JavaScript fundamentals, DOM APIs, and async patterns.
Authoritative Standards & Citations
- ISO/IEC 9899 (C Language Standard) — Official international C specification by ISO/IEC JTC 1/SC 22/WG 14.
- GNU GCC Documentation — Official reference manual for the GNU Compiler Collection and C libraries.
- The C Programming Language (K&R) — Definitive classic work by Brian Kernighan & Dennis Ritchie at Bell Labs.
- C Reference Documentation (cppreference.com) — Verified reference covering C89 through C23 language features.