Cgets(), puts() & fgets()

gets(), puts() & fgets()

Beyond printf and scanf, C's standard library offers a few simpler, line-oriented functions for reading and writing whole lines of text at once. One of them — gets — is so dangerous it was removed from the language standard entirely, and understanding why is itself a valuable lesson in C's approach to safety.

puts() — simple line output

puts writes a string followed by a newline. It's simpler than printf when you just need to print a fixed string with no formatting:

C
#include <stdio.h>

int main(void) {
    puts("Hello, World!");   /* automatically appends '\n' */
    puts("Goodbye!");
    return 0;
}
Hello, World!
Goodbye!
puts always adds a newline
Unlike `printf("Hello, World!")`, which prints exactly the characters you gave it, `puts` **always** appends a trailing newline — you never write `\n` yourself when using `puts`.
gets() — removed from the language for good reason
Never use gets() — it no longer exists in C11 and later
`gets` reads a line of input into a buffer you provide, but it has **no way to know the buffer's size**, so it cannot stop itself from writing past the end of it. Any input longer than the buffer causes a **buffer overflow** — memory corruption that has been at the root of countless real-world security vulnerabilities. The problem was considered so severe that `gets` was formally removed from the C standard in **C11**; a strictly conforming C11 (or later) compiler doesn't even provide it anymore. If you see `gets` in old code or a textbook, treat it purely as a historical cautionary tale, never as something to actually write.

C
char buffer[10];
gets(buffer); /* DO NOT DO THIS -- if the user types more than 9 characters,
                 gets() happily writes past the end of buffer */
fgets() — the safe, modern replacement

fgets reads a line, but takes a maximum size so it can never write past the end of your buffer. Its signature is char *fgets(char *str, int n, FILE *stream) — it reads at most n - 1 characters, always leaving room for the null terminator, and stops early if it hits a newline or end-of-file.

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

int main(void) {
    char buffer[32];

    printf("Enter your name: ");
    if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
        /* fgets keeps the trailing newline if it fits -- strip it */
        size_t len = strlen(buffer);
        if (len > 0 && buffer[len - 1] == '\n') {
            buffer[len - 1] = '\0';
        }
        printf("Hello, %s!\n", buffer);
    }
    return 0;
}
fgets keeps the newline — a common gotcha
Unlike `gets` (which discarded the newline) and `scanf("%s", ...)` (which stops at whitespace), `fgets` includes the newline character `\n` in the buffer if the whole line fit before the size limit was reached. Forgetting to strip it is one of the most common `fgets` mistakes — it shows up as unexpected blank lines or a trailing space-looking artifact when you print or compare the string afterward.
At a glance

Function

Bounds-checked

Keeps the newline

Status

gets

No

No (discards it)

Removed in C11 -- never use

fgets

Yes (you supply the size)

Yes, if it fits

Recommended for reading lines

scanf("%s", ...)

No (unless you specify a width like %31s)

N/A -- stops at whitespace

Use with an explicit width, or avoid for untrusted input