Gets vs fgets in C: Key Differences and Usage Guide
gets reads a line from standard input but is unsafe because it does not limit input size, risking buffer overflow. fgets is safer as it reads up to a specified number of characters, preventing overflow and allowing control over input length.Quick Comparison
Here is a quick side-by-side comparison of gets and fgets functions in C.
| Feature | gets | fgets |
|---|---|---|
| Input size limit | No limit, reads until newline | Limits input to specified size - 1 |
| Buffer overflow risk | Yes, unsafe | No, safer with size limit |
| Includes newline in input | No, newline is removed | Yes, newline is kept if space allows |
| Function prototype | char *gets(char *str) | char *fgets(char *str, int n, FILE *stream) |
| Standard input usage | Reads from stdin only | Can read from any FILE stream |
| Status | Deprecated and removed in C11 | Standard and recommended |
Key Differences
gets reads a line from standard input until it encounters a newline character, but it does not check the size of the buffer it writes into. This means if the input is longer than the buffer, it will overflow and cause undefined behavior, which is a serious security risk. Because of this, gets has been removed from the C11 standard and should never be used in modern code.
On the other hand, fgets requires you to specify the maximum number of characters to read, including the terminating null character. This prevents buffer overflow by limiting input size. Additionally, fgets keeps the newline character if there is space in the buffer, so you may need to remove it manually if you don't want it.
Another difference is that gets only reads from standard input (stdin), while fgets can read from any file stream, making it more versatile. Overall, fgets is safer and more flexible, which is why it is the preferred choice.
Code Comparison
This example shows how to read a string from the user using gets. Note this code is unsafe and for demonstration only.
#include <stdio.h> int main() { char buffer[20]; printf("Enter a string (max 19 chars): "); gets(buffer); // Unsafe, no size check printf("You entered: %s\n", buffer); return 0; }
fgets Equivalent
This example shows the safer equivalent using fgets to read input with size limit and handling the newline.
#include <stdio.h> #include <string.h> int main() { char buffer[20]; printf("Enter a string (max 19 chars): "); if (fgets(buffer, sizeof(buffer), stdin)) { size_t len = strlen(buffer); if (len > 0 && buffer[len - 1] == '\n') { buffer[len - 1] = '\0'; // Remove newline } printf("You entered: %s\n", buffer); } return 0; }
When to Use Which
Choose fgets whenever you need to read strings safely in C, especially from user input, because it prevents buffer overflow by limiting input size and allows you to handle newlines explicitly. Avoid gets entirely as it is unsafe and removed from modern C standards. Use fgets also when reading from files or other streams, making it more versatile for various input sources.