Почему gets не работает в visual studio
Перейти к содержимому

Почему gets не работает в visual studio

  • автор:

gets_s , _getws_s

Получает строку из потока stdin . Эти версии имеют _getws улучшения безопасности, как описано в функциях gets безопасности в CRT.

Синтаксис

char *gets_s( char *buffer, size_t sizeInCharacters ); wchar_t *_getws_s( wchar_t *buffer, size_t sizeInCharacters ); 
template char *gets_s( char (&buffer)[size] ); // C++ only template wchar_t *_getws_s( wchar_t (&buffer)[size] ); // C++ only 

Параметры

buffer
Место хранения входной строки.

sizeInCharacters
Размер буфера.

Возвращаемое значение

Возвращает значение buffer в случае успешного выполнения. Указатель NULL указывает на ошибку или конец файла. Используйте ferror или feof определите, какой из них произошел.

Замечания

Функция gets_s считывает строку из стандартного потока ввода stdin и сохраняет ее в буфере buffer . Строка состоит из всех символов до первого нового символа (‘ \n ). gets_s затем заменяет новый символ null (‘ \0 ) перед возвратом строки. Напротив, функция fgets_s сохраняет символ новой строки.

Если первый символ считывается в конце файла, возвращается пустой символ в начале buffer и NULL возвращается.

_getws_s — это версия функции gets_s для расширенных символов; ее аргумент и возвращаемое значение являются строками расширенных символов.

NULL sizeInCharacters Если buffer значение равно нулю или равно нулю, или если буфер слишком мал для хранения входной строки и конца null, эти функции вызывают обработчик недопустимых параметров, как описано в разделе «Проверка параметров». Если выполнение может быть продолжено, эти функции возвращают NULL и устанавливают параметр errno в значение ERANGE .

В C++ использование данных функций упрощено наличием шаблонных перегрузок; перегруженные методы могут автоматически определять длину буфера (что исключает необходимость указания аргумента с размером буфера), а также они могут автоматически заменять более старые, незащищенные функции их новыми безопасными аналогами. Дополнительные сведения см. в разделе «Безопасные перегрузки шаблонов».

По умолчанию глобальное состояние этой функции ограничивается приложением. Чтобы изменить это поведение, см . статью «Глобальное состояние» в CRT.

Сопоставления подпрограмм универсального текста

TCHAR.H Обычной _UNICODE и _MBCS не определен _MBCS Определенные _UNICODE Определенные
_getts_s gets_s gets_s _getws_s

Требования

Маршрут Обязательный заголовок
gets_s
_getws_s или

Консоль не поддерживается в приложениях универсальная платформа Windows (UWP). Стандартные дескрипторы потока, связанные с консолью, stdin stdout и stderr , должны быть перенаправлены перед тем, как функции времени выполнения C могут использовать их в приложениях UWP. Дополнительные сведения о совместимости см. в разделе Совместимость.

Пример

// crt_gets_s.c // This program retrieves a string from the stdin and // prints the same string to the console. #include int main( void ) < char line[21]; // room for 20 chars + '\0' gets_s( line, 20 ); printf( "The line entered was: %s\n", line ); >
Hello there! 
The line entered was: Hello there! 

gets , _getws

Получает строку из потока stdin . Доступны более безопасные версии этих функций; see gets_s , _getws_s .

Эти функции устарели. Начиная с Visual Studio 2015 они недоступны в CRT. Безопасные версии этих функций gets_s и _getws_s по-прежнему доступны. Дополнительные сведения об этих альтернативных функциях см. в разделе gets_s . _getws_s

Этот API нельзя использовать в приложениях, выполняемых в среде выполнения Windows. Дополнительные сведения: Функции CRT, которые не поддерживаются в приложениях универсальной платформы Windows.

Синтаксис

char *gets( char *buffer ); wchar_t *_getws( wchar_t *buffer ); template char *gets( char (&buffer)[size] ); // C++ only template wchar_t *_getws( wchar_t (&buffer)[size] ); // C++ only 

Параметры

buffer
Место хранения входной строки.

Возвращаемое значение

В случае успеха возвращает свой аргумент. Указатель NULL указывает на ошибку или конец файла. Используйте ferror или feof определите, какой из них произошел. Если buffer это NULL так, эти функции вызывают недопустимый обработчик параметров, как описано в разделе «Проверка параметров». Если продолжение выполнения разрешено, эти функции возвращают NULL и устанавливают для errno значение EINVAL .

Замечания

Функция gets считывает строку из стандартного потока ввода stdin и сохраняет ее в буфере buffer . Строка состоит из всех символов до первого символа новой строки («\n»). Затем перед возвратом строки функция gets заменяет символ новой строки нуль-символом («\0»). Напротив, функция fgets сохраняет символ новой строки. _getws — это версия функции gets для расширенных символов; ее аргумент и возвращаемое значение являются строками расширенных символов.

Так как количество символов, считываемых ненадежными gets , может легко привести к переполнению буфера. Вместо этого используйте fgets .

В C++ эти функции имеют шаблонные перегрузки, которые вызывают более новые и безопасные аналоги этих функций. Дополнительные сведения см. в разделе «Безопасные перегрузки шаблонов».

По умолчанию глобальное состояние этой функции ограничивается приложением. Чтобы изменить это поведение, см . статью «Глобальное состояние» в CRT.

Сопоставления подпрограмм универсального текста

Подпрограмма TCHAR.H _UNICODE и _MBCS не определен _MBCS Определенные _UNICODE Определенные
_getts gets gets _getws

Требования

Маршрут Обязательный заголовок
gets
_getws или

Дополнительные сведения о совместимости см. в разделе Совместимость.

Пример

// crt_gets.c // compile with: /WX /W3 #include int main( void ) < char line[21]; // room for 20 chars + '\0' gets( line ); // C4996 // Danger: No way to limit input to 20 chars. // Consider using gets_s instead. printf( "The line entered was: %s\n", line ); >

Входные данные дольше 20 символов перезапустят буфер строки и почти наверняка вызывают сбой программы.

 Hello there!The line entered was: Hello there! 

Почему gets не работает в visual studio

Здравствуйте. У меня возникли проблемы с функцией gets().

#include «stdafx.h»
#include
#include
using namespace std ;

И возник у меня вопрос. Почему когда я ввожу русский текст, в поле «Введите строку», в графе «Вот введенная Вами строка» оно выводит иероглифы? А вот с английским текстом все нормально.

Форумчанин
Регистрация: 26.07.2011
Сообщений: 376

Попробуй подключить данную библиотеку
попробуйте данный вариант

#include "stdafx.h" #include #include #include  < добавлено >using namespace std; int main() < SetConsoleCP(1251);< добавлено >SetConsoleOutputCP(1251); < добавлено >setlocale(LC_ALL, "rus"); char sample[40]; cout

Там где добавил, оставил комментарий.
Люблю на ты.Я человек простой
Пользователь
Регистрация: 21.10.2012
Сообщений: 65

Так оно вообще не воспринимает русский. Хотя если переключить шрифт в консоли на Lucida Console все прекрасно работает. Но будет ли оно работать где либо, вне моего компьютера?

Хотя если изменить расположение файла, или поменять ему имя и т.д оно опять не работает, сбивается шрифт.

А можно еще как-нибудь исправить проблему с русским языком?

Последний раз редактировалось apeorin; 22.10.2012 в 09:05 .
Белик Виталий 🙂
Регистрация: 23.07.2007
Сообщений: 57,792

А почему через gets()
У тебя же есть iostream, а соответственно открыта дорога для cin и wcin для юникода (кажется так этот класс называется)

I’m learning to live.
Пользователь
Регистрация: 21.10.2012
Сообщений: 65

Если использовать cin то оно будет считывать и выводить текст до первого пробела. У меня проблема с выводом русского текста в графе «Вот введенная Вами строка: «.

Последний раз редактировалось apeorin; 22.10.2012 в 09:00 .
Пользователь
Регистрация: 01.11.2011
Сообщений: 42

Надеюсь что помог :

void main() < setlocale (LC_ALL,"RUS"); char sample[40]=; cout

Сам давно искал ответ , ну собственно - у меня на 2008 VS все окейно работает
Пользователь
Регистрация: 21.10.2012
Сообщений: 65
Сообщение от zipo666

Надеюсь что помог :

void main() < setlocale (LC_ALL,"RUS"); char sample[40]=; cout

Сам давно искал ответ , ну собственно - у меня на 2008 VS все окейно работает

1>d:\visual studio 2010\projects\13\13\13.cpp(16): warning 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.
1> d:\program files\microsoft visual studio 10.0\vc\include\stdio.h(277): см. объявление "gets"
1>d:\visual studio 2010\projects\13\13\13.cpp(18): error C2664: OemToCharW: невозможно преобразовать параметр 2 из "char [40]" в "LPWSTR"
1> Типы, на которые указывают указатели, не связаны; для преобразования требуется reinterpret_cast, приведение в стиле С или приведение в стиле функции

Функции gets и gets_s. В чем опасность

При использовании функции gets , компилятор Microsoft выдает предупреждение о том, что она опасная и предлагает использовать безопасную версию — gets_s. Однако функция gets_s работает только с компилятором Microsoft, а под Linux ее вообще нет. Расскажите в чем опасность этой функции, за счет чего функция gets_s безопаснее и как решить проблему с переносимостью.

21.07.2016 в 04:25 #2965
MSDN описывает функцию gets как устаревшую:

These functions are obsolete. Beginning in Visual Studio 2015, they are not available in the CRT. The secure versions of these functions, gets_s and _getws_s, are still available

Компилятор gcc также выдает предупреждение о том, что функция устаревшая:

warning: ‘char* gets(char*)’ is deprecated [-Wdeprecated-declarations]

В Linux man рассказано об опасностях использования этой функции:

Never use gets(). Because it is impossible to tell without knowing the
data in advance how many characters gets() will read, and because
gets() will continue to store characters past the end of the buffer, it
is extremely dangerous to use. It has been used to break computer
security. Use fgets() instead.

Таким образом, использование функции gets не рекомендуется нигде. Проблема функции в том, что она считывает данные в буфер до тех пор, пока не встретится символ конца строки, не учитывая размер буфера. Т.е., например, если мы выделим память под 25 символов, а пользователь введет строку из 40 символов, то следующие за строкой 15 байт будут перезаписаны. Такая ошибка может привести к чему угодно, причем программа может продолжать работать, но делать это неправильно (ошибку очень сложно выявить). Описанные проблемы показаны следующим кодом:

#include struct Item < char name[8]; int cost; >; int main(void)

Поля структуры располагаются в памяти последовательно, поэтому если пользователь введет название предмета более чем из семи символов (восьмым будет символ окончания строки), то стоимость предмета изменится: gets_problem_exampleПроблемы использования gets Если теперь мы поменяли бы еще раз стоимость предмета — изменилось бы и содержимое строки. Microsoft предлагает решать проблему с помощью gets_s — эта функция принимает на вход не только буфер, но и размер буфера. В случае ошибки (буфер равен NULL или размер буфера недостаточен для сохранения введенной строки) функция возвращает NULL . Кроме того, gets_s может вызывать специальный обработчик ошибок. Стандартная библиотека предлагает другое решение — функцию fgets , которая также принимает на вход размер буфера: char *fgets(char *s, int size, FILE *stream); Функция позволяет считывать данные с файла, а если требуется ввод с клавиатуры — в качестве третьего аргумента нужно передавать stdin . Если пользователь введет более size символов, будет записано лишь первые size байт, а остальные символы останутся в файле нетронутыми. Заменив в приведенном выше коде ввод данных на
fgets(item.name, 8, stdin);
Мы получим другой вывод программы (теперь вводится только часть имени предмета, но не портятся данные и программа остается корректной. fgets_exampleИспользование gets вместо gets

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *