std::gets(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’œ std::gets πŸ’œ

ok so real talk bestie, you're looking at the C++ Standard Libary manual page for std::gets, and the vibe check on this one is... rough. like, this function got removed from the language. but we're gonna learn about it anyway because knowing why something is iconic-and-terrible is part of being a real one. 🫢


✨ NAME ✨

std::gets β€” literally just std::gets, the function so nice they named it... okay no, the function so dangerous they deprecated it πŸ’€


🌸 Synopsis 🌸

okay so first thing, it lives in this header:

Defined in header <cstdio>

and here's the signature, look at it, look at this mess:

char* gets( char* str );    (deprecated in C++11)
                            (removed in C++14)

what it does is: reads stdin into the given character string until a newline character is found or end-of-file occurs. that's it. that's the whole bit. no length. no checks. no thoughts, head empty. πŸŽ€


πŸ¦‹ Parameters πŸ¦‹

  • str β€” the character string to be written into. it's a char*, it's yours, and nobody's gonna tell you how big it is (this is the entire problem, iykyk).

⭐ Return value ⭐

  • str on success πŸ’–
  • a null pointer on failure πŸ™ˆ

and the failure has layers, bestie, so listen up:

  • if the failure has been caused by an end of file condition, it additionally sets the eof indicator (see std::feof()) on stdin.
  • if the failure has been caused by some other error, it sets the error indicator (see std::ferror()) on stdin.

see, it's not *un*informative. it's just... unsafe. different thing. πŸ’…


πŸ”₯ Notes πŸ”₯

okay here's the main character moment nobody asked for: the std::gets() function does not perform bounds checking. so this function is extremely vulnerable to buffer-overflow attacks. like, astronomically. it cannot be used safely β€” unless the program runs in an environment which restricts what can appear on stdin.

🚨 for this reason, the function was deprecated in C++11 and removed altogether in C++14. she's gone. she is not coming back. std::fgets() may be used instead, and honestly bestie, use it. periodt.

🧚 Example 🧚

here's the sample, and note the first line of it β€” the code itself is telling you not to use it, that's so real of it:

// Run this code

#include <array>
#include <cstdio>
#include <cstring>

int main()
{
    std::puts("Never use std::gets(). Use std::fgets() instead!");

    std::array<char, 16> buf;

    std::printf("Enter a string:\n>");

    if (std::fgets(buf.data(), buf.size(), stdin))
    {
        const auto len = std::strlen(buf.data());
        std::printf(
            "The input string:\n[%s] is %s and has the length %li characters.\n",
            buf.data(), len + 1 < buf.size() ? "not truncated" : "truncated", len
        );
    }
    else if (std::feof(stdin))
    {
        std::puts("Error: the end of stdin stream has been reached.");
    }
    else if (std::ferror(stdin))
    {
        std::puts("I/O error when reading from stdin.");
    }
    else
    {
        std::puts("Unknown stdin error.");
    }
}

πŸ’« Possible output πŸ’«

Never use std::gets(). Use std::fgets() instead!
Enter a string:
>Living on Earth is expensive, but it does include a free trip around the Sun.
The input string:
[Living on Earth] is truncated and has the length 15 characters.

15 characters bestie. the buffer said "that's all I have" and the string kept going. that is exactly the energy we're avoiding. 😭


🌈 See also 🌈

  • scanf β€” reads formatted input from stdin, a file stream or a buffer
  • fscanf β€” (function, same family as above)
  • sscanf β€” (function, same family as above)
  • fgets β€” gets a character string from a file stream (function) β€” ✨ the replacement, the saviour, the one you should actually call
  • fputs β€” writes a character string to a file stream (function)
  • C documentation for gets β€” yes, C has one too. yes, same warnings apply. πŸ‘‘

πŸ’€ one last vibe check: std::gets = removed, std::fgets = the move. don't be the girl who pipes unbounded input into a fixed array. be the girl who passes buf.size().

and that's the page! πŸŽ€ this one came to you from http://cppreference.com, dated 2024.06.10 β€” go drink some water, then go call std::fgets(), love u, bye! πŸ’–βœ¨

πŸ“¦ where this page comes from