why gets() is not working?
I am programming in C in Unix, and I am using gets to read the inputs from keyboard. I always get this warning and the program stop running:
Can anybody tell me the reason why this is happening?
4 Answers 4
gets is unsafe because you give it a buffer, but you don’t tell it how big the buffer is. The input may write past the end of the buffer, blowing up your program fairly spectacularly. Using fgets instead is a bit better because you tell it how big the buffer is, like this:
. so provided you give it the correct information, it doesn’t write past the end of the buffer and blow things up.
Slightly OT, but:
You don’t have to use a const int for the buffer size, but I would strongly recommend you don’t just put a literal number in both places, because inevitably you’ll change one but not the other later. The compiler can help:
That expression gets resolved at compile-time, not runtime. It’s a pain to type, so I used to use a macro in my usual set of headers:
. but I’m a few years out of date with my pure C, there’s probably a better way these days.
Почему не работает gets c
Many thanks for your help!

Sigh, perhaps we should make a sticky or pinned thread on the solution to this common problem.
After line 11 add this cin.get(); ;
Problem solved — it was just a trailing new line which functions like gets() use to determine the end of input.
Also, use the C++ getline() — it is far more safer than the C gets().
Try not to mix C and C++ functions.
About the getch(), don’t use it. It is non-standard. You are using <conio2.h>, which is also non-standard.
If you really must use getch and you are on Windows, use this instead: http://www.cplusplus.com/forum/articles/19975/
Another thing, in C++ use instead of what you’re doing on line 2.

Many thanks unoriginal, now it works OK after the adding of cin.get() ;
However when I try to use the getline() I get a error:
no matching function for call to `getline(char[20])’

Twenty characters isn’t very much space for a complete name. What if my name were «Viacheslav Kalishnikov»? Or «Maria Sanchez Hernandez»? Etc.
Hope this helps.
[edit] Fixed typo. (Thanks mcleano.) [/edit]

Many thanks but the preferred solution gives me the following error
no matching function for call to `getline(std::string&)'
and the alternate solution gives me these:
no matching function for call to `std::basic_istream<char, std::char_traits<char> >::getline(char[20])'
note D:\wxDevcppPortable7\App\devcpp\include\c++\3.4.5\bits\istream.tcc:582 candidates are: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::getline(_CharT*, std::streamsize, _CharT) [with _CharT = char, _Traits = std::char_traits<char>]
Oh and the program is only a test one to check the gets() fault that I got from a other huge program so don’t worry for the 20 character length of the name and surname 🙂
Many thanks and sorry for my inexperience 🙁

It sounds like your STL is broken or you are not #including the proper headers. MinGW 3.4.5 sufficiently conforms to the C++ standard that both functions are properly available.
Please don’t use the C library gets(). It is a security flaw and should never have been included in the language library. If you must use the C FILE* methods, use fgets(), then just strip the newline from the end of the string. Here’s a little function to do it:
That’s the same as gets() but without the possibility of buffer overruns:
safe_gets( name_surname, 20 );
If you are using C++, though, you are still better off using the C++ methods.
Good luck!
Почему происходит пропуск функции считывания строки gets_s?

Вызов gets_s() проскакивает потому, что при вводе по cin ты нажимаешь Enter в конце. Когда нажимаешь Enter, в поток посылается символ перевода строки и остаётся там. А потом gets_s() видит его и считает введённой строкой. Поэтому ты должен после cin выполнить cin.get()
Вот это число 10 — это код символа \n (символа перевода строки).
Почему не работает gets c
![]()
Лучший отвечающий
Вопрос
Почему оно ругается на функцию gets()? Пробовал и gets_s, и scanf, и scanf_s, но везде выдаёт ошибку. Проект пересоздавал — тоже не помогло. Я бы прикрепил сюда скрин, но тут какие-то ограничения, в которых мне лень разбираться. Поэтому ниже будет код программы и текст ошибки.
1 #include "stdafx.h"
2
3 class isdelie <
4 char *name, *cipher;
5 int amount;
6 public:
7 void vvod() <
8 puts("Enter the name:");
9 fflush(stdin);
10 gets(name);
11 puts("Enter the cipher:");
12 fflush(stdin);
13 gets(cipher);
14 puts("Enter the amount:");
15 scanf_s("%d", &amount);
16 >
17 void vivod() <
18
19 >
20 isdelie() <
21 >
22
23 >;
24
25 int _tmain(int argc, _TCHAR* argv[])
26 <
27
28 return 0;
29 >
Ошибка 1 error C4996: ‘gets’: This function or variable may be unsafe. Consider using gets_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
*ссылка на 10 строку*
Ответы
Учитесь делать все правильно, а не абы как.
Вы думали неверно, память выделяет тот кто вызывает функцию (типично и в данном случае). Но даже если бы память и выделялась бы, как бы вы получили на нее указатель? Ведь изменить переданный вами указатель невозможно, выходит что его передача вообще бесполезна.
Да, не на долго будет задействована "лишняя" память. Привыкайте, это обычное дело. Будете выделять память под максимальный ожидаемый размер строки, вот и все. Потом строка копируется по размеру или же сразу используется и память освобождается.
This posting is provided "AS IS" with no warranties, and confers no rights.
- Помечено в качестве ответа Zhenya Vasiliev 23 сентября 2017 г. 13:00
Все ответы
Дело в том что эта функция небезопасна и часто вызывает переполнение буфера что обычно приводит к AV. Вместо той функции следует использовать функцию gets_s (или fgets как вам уже посоветовали). Кстати, это написано в сообщении об ошибке, там же написано как запретить проверку.
Далее, вы забыли выделить память для ваших строк. Ваше приложение должно упасть с AV если вы его запретите проверку как написано в сообщении и компиляция пройдет успешно.
Еще один момент: не используйте char для символов/строк, это приводит к проблемам с локализацией. Используйте Unicode (WCHAR или TCHAR и функции для работы с ними). Для меня загадка почему в США (где нет проблем с местными символами) уже
20 лет как используют Unicode, а в России (где такие проблемы имеются) все упорно пытаются использовать 8 битные символы чтоб потом героически бороться с "квадратиками" и "иероглифами" вместо кириллицы.
This posting is provided "AS IS" with no warranties, and confers no rights.