精华内容
下载资源
问答
  • gets_s函数
    千次阅读
    2021-11-22 21:25:37
    1. 它防止缓冲区溢出的方式与fgets()类似,即用一个参数限制读入的字符数

    2. gets_s()函数只从键盘得到输入,所以gets_s函数的内部代码中就有了stdin,不像fgets()函数有多种输入方式,故它没有第三个参数。

    3. gets_s()函数读到换行符同gets()函数一样,将换行符丢掉而不是储存它

    4. 如果gets_s()函数读到最大字符数都没有读到字符串的结束标志换行符,这时它会首先把目标数组中的首字符设置为空字符,会读取在达到最大字符数量后的输入,而且也要丢弃这随后的输入直到读到换行符或文件末尾,然后返回空指针。这样可能会中止或退出程序

    更多相关内容
  • 使用C语言gets函数和gets_s函数,读取含空格的字符串

    导读

     在刷Oj题时,遇到包含空格的字符串输入,如何读取呢?如果使用scanf%s格式去读取输入的字符串,遇到空格就读取结束了,显然这样是读取不了的。当然,scanf也是可以读取含空格字符串的,但操作起来相对较难,对C语言初学者并不友好。下面开始介绍两个可以对含空格字符串读取的库函数------getsgets_s函数


    gets函数

    函数声明

    char * gets ( char * str );
    

    函数介绍

    头文件

    #include<stdio.h>

    从stdin获取字符串

    从标准输入(stdin)中读取字符(包括空格,Tab),并将其作为C字符串存储到str中,直到到达换行符或文件结尾。

    如果找到换行符,则不会将其复制到str中。

    在复制到str的字符之后,将自动追加终止的空字符

    请注意getsfgets完全不同:gets不仅使用stdin作为源,而且在结果字符串中不包含结尾的换行符,并且不允许指定str的最大大小(这可能导致缓冲区溢出

    参数

    str

    指向内存块(字符数组)的char*型指针,其中读取的字符串作为C字符串复制。

    返回值

    成功时,函数返回str(返回输入字符串的起始位置)

    读取结束(读取到'\n')或读取失败时,函数返回空指针(NULL)。

    以下两行了解即可

    如果在尝试读取字符时遇到文件结尾,则设置EOF指示符(FEOF)。如果在读取任何字符之前发生这种情况,则返回的指针为空指针(NULL)(str的内容保持不变)。

    如果发生读取错误,将设置错误指示符(ferror),并返回空指针(NULL)(但str指向的内容可能已更改)。

    兼容性

    C标准的最新修订版(2011年)已明确将该功能从其规范中删除。

    该函数在C++中被禁止(如2011个标准,它遵循C9+TC3)。


    用法实例(在DEV-C++编译器环境底下,Visual Studio 2019并不支持gets函数)

    eg1:多组输入含空格字符串,输出其字符串长度和字符串

    #include<stdio.h>
    #include<string.h>
    
    int main()
    {
    	char str[100] = { 0 };
    	int len=0;
    	while(gets(str) != NULL)	//gets函数的多组输入写法,读取结束或失败时返回NULL,注意和scanf函数的多组输入结束或失败返回值EOF区分开 
    	{
    		len = strlen(str);
    		printf("输入的字符串%s长度是%d\n", str, len);
    	}
    	
    	return 0;
    }

    eg2:使用动态内存分配函数返回的指针接收输入的含空格的字符串

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    int main()
    {
    	char* str = (char*)calloc(100, sizeof(char));
    	//char* str = (char*)malloc(100 * sizeof(char));
    	int len=0;
    	
    	if(str != NULL)
    	{
    		while(gets(str) != NULL)	//gets函数的多组输入写法,读取结束或失败时返回NULL,注意和scanf函数的多组输入结束或失败返回值EOF区分开 
    		{
    			len = strlen(str);
    			printf("输入的字符串%s长度是%d\n", str, len);
    		}
    
    		
    		free(str);
    		str=NULL;
    	}
    
    	return 0;
    }

    eg3:由于目标指针str不允许指定str的最大大小(这里指内存空间大小)(这可能导致缓冲区溢出

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    
    int main()
    {
    	char str[3] = { 0 };//创建可以存放三个字符的数组 
    	int len=0;
    	//输入字符串abcdef(超过str数组长度) 这种情况下的输出依然可以得到期望的值。
        //但是,这也体现了gets函数在某些情况下可能会导致缓冲区溢出,这是一个不安全的函数 
    	while(gets(str) != NULL)	//gets函数的多组输入写法,读取结束或失败时返回NULL,注意和scanf函数的多组输入结束或失败返回值EOF区分开 
    	{
    		len = strlen(str);
    		printf("输入的字符串%s长度是%d\n", str, len);
    	}
    	
    	return 0;
    }

    gets_s函数

    函数声明

    char * gets_s( char * buffer,  size_t  sizeInCharacters );


    函数介绍

    头文件

    #include<stdio.h>

    参数

    buffer
    输入字符串的存储位置,char*型指针。

    sizeInCharacters
    缓冲区的大小。

    返回值

    如果成功,则返回 buffer。 NULL 指针指示错误或文件尾条件。 使用 ferror 或 feof 来确定发生了哪一个。

    注解

    gets_s 函数从标准输入流 stdin 中读取一个行并将该行存储在 buffer中。 该行由所有字符组成,其中包含第一个换行符 ( " \n " ) 。 gets_s 然后,在返回行之前将换行符替换为空字符 ( " \0 " ) 。 相反, fgets_s 函数将保留换行符。

    如果读取的第一个字符是文件尾字符,则空字符将存储在 buffer 的开头,并返回 NULL

    _getws_s 是 gets_s 的宽字符版本;其参数和返回值都是宽字符字符串。

    如果 buffer 为 NULL 或 sizeInCharacters 小于或等于零,或者如果缓冲区太小,无法包含输入行和 null 终止符(小写的null空字符 ( " \0 " )),这些函数将调用无效参数处理程序,如buffer中所述。 如果允许执行继续,则这些函数返回 NULL 并将 errno 设置为 ERANGE

    以下两行了解即可

    在 C++ 中,使用这些函数由模板重载简化;重载可以自动推导出缓冲区长度 (不再需要指定大小自变量),并且它们可以自动用以更新、更安全的对应物替换旧的、不安全的函数。 有关详细信息,请参阅安全模板重载

    默认情况下,此函数的全局状态的作用域限定为应用程序。 若要更改此项,请参阅 CRT 中的全局状态


    用法实例(由于gets_s是Visual Studio 编译器提供的安全gets函数,因此仅在该编译器环境底下可以使用)

    eg1:多组输入,多组输出,求含空格字符串长度,以char类型型数组存放

    #include<stdio.h>
    #include<string.h>
    
    #define SZ 10  //根据实际输入情况定义最长字符串长度+1即可,增加1是为了给'\0'留位置,这里最长可输入9长度的字符串
    
    int main()
    {
        int len = 0;
        char str[SZ] = { 0 };
    
        while (gets_s(str, SZ) != NULL)//这里只能输入不超过SZ-1长度的字符串,否则程序崩溃,这也体现出gets_s函数的安全性极高
        {
            len = strlen(str);
            printf("输入的字符串%s长度为%d", str, len);
        }
    
        return 0;
    }

    eg2:多组输入,多组输出,输入处理含空格的字符串,以动态内存分配函数形式

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    #define SZ 10  //根据实际输入情况定义最长字符串长度+1即可,增加1是为了给'\0'留位置,这里最长可输入9长度的字符串
    
    int main()
    {
        int len = 0;
        char* str = (char*)malloc(SZ * sizeof(char));
       // char* str = (char*)calloc(SZ, sizeof(char));
    
        while (gets_s(str, SZ) != NULL)//这里只能输入不超过SZ-1长度的字符串,否则程序崩溃,这也体现出gets_s函数的安全性极高
        {
            len = strlen(str);
            printf("输入的字符串%s长度为%d", str, len);
        }
    
        free(str);
        str=NULL;
    
        return 0;
    }

     学习小结

    这两个函数给我们提供了一种新的读取字符串的方式,与scanf函数读取字符串的区别就在于它们可以读取含空格,Tab的字符串。解决关于字符串OJ问题的关键一步,读取输入的字符串就得到有效的解决了。

    在DEV-C++编译器环境底下,直接调用gets函数即可;在Visual Studio 2019等VS编译器底下,gets函数被gets_s函数取代,调用gets_s函数即可。

    这两个函数,注意传递的参数,在提交到OJ系统上时,应该使用gets函数,因为OJ系统上的编译环境其实是DEV。


    给大家西大OJ上的一道处理含空格字符串的题目,OJ练习:OnlineJudge

    西大OJ时常会出现崩溃情况,我还是把题目放底下给大家吧。


     题外话

    今天是2021年12月18日,是的,今天是英语四六级考试。我已经寄了,只能明年继续冲了,在这里记录一下今天,这是一个悲伤的故事。

    上午11:20考完试,我就回宿舍做上面那道OJ题。17日的晚上,我做到这道题目时,挨卡了,以前处理字符串的题目是不包含空格的,因此我也是查了很多的资料,但是发现,CSDN上关于处理含字符串函数的介绍并不理想,因此,在我AC这个题目后,我进行了这次学习总结。

    查了很多种处理含空格字符串处理方法,最终我选择介绍gets和gets_s函数,这对于C语言初学者来说,是比较好理解和操作的,上面的介绍中也对函数的使用给了具体的例子。

    这篇博客,干货多多,建议一键三连,同时希望它可以帮助到C语言初学者。

    展开全文
  • 最近做游戏编辑器,自己试着用C/C++写了一个读取简单配置表的函数,在控制台下测试的时候,使用了C的标准库gets函数,发现编译器报告gets函数unsafe,网上搜索了一下,发现gets函数不对接受字符串的buffer进行边界...

    最近做游戏编辑器,自己试着用C/C++写了一个读取简单配置表的函数,在控制台下测试的时候,使用了C的标准库gets函数,发现编译器报告gets函数unsafe,网上搜索了一下,发现gets函数不对接受字符串的buffer进行边界检测,会造成越界,从而产生bug;自己写的东西,也是自己用的东西,当然可以在定义配置表的时候得到控制,从而不会使越界的情况出现,但是总的来说这不是一个好的思考方式;于是按照网上的提示改用了fgets函数替代;

    使用fgets函数后,就发现问题了,原来的代码不能正常工作了,调试了一通,发现使用fgets函数获取的字符串与gets函数获取的不一样,fgets函数获取的字符串会在buffer里面保留换行符,而gets函数不会;好吧,问题找到了,解决也很简单,把最后一个换行符拿掉,换成'\0'就可以了。然后,又发现有个gets_s函数,可以像gets一样不会获取换行符,也不会有gets的越界问题,然后在cppreference.com查看了这几个函数的描述,却发现gets_s函数是一个标准库扩展函数,一个可选项;所以就不知道这个gets_s函数在各个编译器下的支持情况如何!作罢,还是使用fgets函数吧。

    这里所引起的思考是:很多的库函数都有着一些很细节的限制,而它的reference一般都会有详细的描述,这就得在使用库函数时去详细的了解库的条件和限制,以免因对库的片面理解,而造成bug.

    展开全文
  • 先来讲讲大家最熟悉的gets()函数。1.gets()函数不安全。2.C11标准委员会已经将其废除,建议能不用尽量不用。解释:gets()函数的作用:它读取整行输入,直至遇到换行符,然后丢弃换行符,储存其余字符,并在其末尾添加...

    先来讲讲大家最熟悉的gets()函数。

    1.gets()函数不安全。

    2.C11标准委员会已经将其废除,建议能不用尽量不用。

    解释:

    gets()函数的作用:它读取整行输入,直至遇到换行符,然后丢弃换行符,储存其余字符,并在其末尾添加一个空字符使其成为一个字符串。

    听起来挺安全的,问题在于gets()函数不检查函数边界,有多少字符它就给你输入多少(来者不拒),这就造成了一个问题:缓冲区溢出(buffer overflow)。这意味着:如果他们有可能擦掉程序中的其他数据(即把数据放到了存储别的数据的地方并将其覆盖)这样就很容易出现问题。

    gets()的替代品:

    fgets()

    get_s()

    s_gets()

    一. fgets()

    fgets()通过第2个参数来限制读入的字符数来解决溢出问题。

    函数专门用于处理文件输入,一般情况下不是很好用。

    解释:

    fgets()函数的第2个参数指明了读入字符的最大数量。如果参数是n,那么fgets()函数将读入n-1个字符,在最后加上空字符。或者读到遇到的第一个换行符为止。(也就是说:一旦读入的字符超过n-2将没有读入换行符)并将换行符储存在字符串中(注意与gets()对比)fgets()函数的第三个参数指明要读入的文件,如果读入从键盘输入的数据,则以stdin1(标准输入)作为参数,该标识符定义在stdio.h中。

    #include

    #define SIZE 10

    int main ()

    {

    char words[SIZE];

    fgets(words,SIZE,stdin);

    fputs(words,stdout);

    return 0;

    }

    fgets()函数的用法,大家体会一下。

    二.gets_s()函数

    gets_s()只从标准输入中读取数据,所以起形式为

    gets_s(char *p,int n);//n表示其最多读取的数量,一般为数组大小

    gets_s()读到换行符,会丢弃它。

    如果输入行太长,gets_s()会丢弃该输入行的其余字符。

    解释:

    其优越性在于第三点:正常来讲,输入行中多出来的字符会被留在缓冲区中,成为下一次读取语句的输入。如果下一次读取的是int 或者double类型,就可能导致程序崩溃。但优点同时也是缺点,因为在其抛弃字符的同时并不会告知我们,一旦输入出现问题我们必须自己查找。

    对于平时的应用大致了解这些就够了,主要了解一下用法,通常情况下我们是不会数组越界的。但是我想说的是fgets()和gets_()函数还有很多细节没有讨论,还有一些奇奇怪怪的用法等着我们去讨论。

    stdin是C语言中标准输入流,一般用于获取键盘输入到缓冲区里的东西。 ↩︎

    展开全文
  • (新)函数调用格式:gets_s(str,参数) 参数:参数为存储字符串的空间长度 函数功能:在标准输入设备输入一个字符串,以"回车键"结束,并把字符串 存放到 str 指定的字符数组或存储区域中。 标准输入函数scanf_s(%...
  • C语言的字符串输入函数gets_s()

    千次阅读 2020-06-26 21:11:33
    C语言的字符串输入函数gets_s() C11新增了gets_s()函数(可选),和fgets()函数类似(上一篇博客有介绍《 C语言的字符串输入fgets()函数 》),用一个参数限制读入的字符数。gets_s()函数的形式如下: gets_s(words...
  • C语言关于指针,gets()和gets_s()函数的理解 使用const修饰一个指针 int a[5] = {0, 1, 2, 3, 4}; //第一种,指针p1不能修改指向地址上的值。 const int * p1 = a; //第二种,指针p2不能更改它所指向的地址。 int * ...
  • C语言--gets()、gets_s()、fget()的比较
  • 在C++读取一行字符串时,可以用函数getline 和 gets,在VC++2010,gets可以使用,但是在VS2019中,需要用到更安全的函数gets_s。 在使用gets_s时,只需要一个参数,用char数组存储的字符串,也就是C语言的字符串存储...
  • char *gets(char *s); int puts(const char *s); gets()函数用于读取整行输入,直到遇到换行符,然后丢弃换行符,存储其余字符,并且在这些字符后面...通常,gets()函数是不安全的,因为gets()函数只有一个参数s用...
  • gets()常用来输入字符串,遇到空格与TAB键不会结束,遇到ENTER键结束,gets()函数读取ENTER键但不保存, 用’\0’取代’\n’ 。 #include int main() { char a[10],b; gets(a); printf("%s", a); b = getchar...
  • 手动实现 gets_s 函数

    2020-05-31 01:27:25
    这两天看到再C11标准中,对于 gets 函数说了一些危险,并...char *gets_s(char * buffer, int num) //gets_s函数gets_s手工实现 { if (fgets(buffer, num, stdin) != 0) { size_t len = strlen(buffer); if (l
  • gets 函数 - fgets 函数 - scanf 函数 - 字符串最后一个单词的长度 1. gets 函数 在 C 语言中,while 循环的功能和它在其他语言中一样。它首先测试表达式的值,如果是假的 (0) 就跳过循环体。如果表达式的值是真的 ...
  • 查了一下书只解释了gets_s()函数输入后会返回接受字符串存储的地址,尝试接受返回值后并没有解决问题。后来百度发现,gets_s()函数在输入时遇到‘\0’就截止输入,而回车键在ASCLL码中就是‘\0’表示。因此程序在...
  • gets()gets_s()puts()函数的使用

    万次阅读 2013-10-13 13:05:36
    从stdin流中读取字符串,直至接受到换行符或EOF时停止... gets 包含头文件  string.h  从stdin流中读取字符串,直至接受到换行符或EOF时停止,并将读取的结果存放在buffer指针所指向的字符数组中。换行符不作为读取
  • gets()、fgets()、gets_s()、s_gets()

    千次阅读 2020-09-10 10:40:13
    gets()、fgets()、gets_s()、s_gets() 1、gets()
  • 这个不用说了吧,scanf("%s",a);就能将输入存储到a这个数组里面。 问题 scanf函数遇到空字符就会结束,(空字符有空格、回车、tab键等等),所以当你输入 i love you 时,数组内存储的就是一个i了,这样的程序七夕节...
  • gets,fgets,gets_s的区别分析

    千次阅读 多人点赞 2020-08-07 15:48:45
    在最开始学习字符串时,我们最常用的输入字符串函数就是——gets(); 这个函数将输入缓冲区中的数据存储到字符型数组中,以换行符结束,并丢弃末尾的换行符添加一个空字符。他解决了scanf("%s",str);以空白符为截至的...
  • C语言gets()和get_s()函数

    万次阅读 多人点赞 2020-02-24 13:11:14
    C语言gets()和get_s()函数 介绍 gets()可以无限读取,易发生溢出。如果溢出,多出来的字符将被写入到堆栈中,这就覆盖了堆栈原先的内容,破坏一个或多个不相关变量的值,由于可以无限读取,所以在2011年12月,ANSI ...
  • C语言gets_s, _getws_s函数了解

    万次阅读 多人点赞 2012-12-11 16:18:55
    gets_s 对应头文件 _getws_s对应头文件 or ...char *gets_s(char *buffer,size_t sizeInCharacters);...wchar_t *_getws_s(wchar_t *buffer,size_t ...与gets函数类似。 _getws is a wide-character
  • s_gets()函数解析

    2022-03-05 15:04:53
    在学习《C primer plus》时,有一个获取输入的函数s_gets()出现频率非常高,此处记录下对这个函数的理解,该函数首次出现于程序清单11.10。 函数源代码: char *s_gets(char *st, int n) { char *ret_val; ...
  • (其实不知道写什么第一代 gets(函数首先呢,gets()函数简单易用,它读取整行输入,直至遇到换行符(\n,然后丢弃换行符,储存其余字符,并这些字符的末尾添加一个空字符 使其成为一个 C 字符串。它经常和 puts()函数...
  • 因为目前GCC中还没有完全实现此标准, 因此 gets_s() 函数尚未包含在目前的GNU 工具链中。Clang里也暂时没有增加对 gets_s 的支持。所以需要在程序中自己实现一个gets_s()函数 char *gets_s(char *str, int num) { ...
  • C语言笔记——gets_s, fgets, puts函数

    千次阅读 2017-09-17 20:01:40
    1. gets_s——相当于scanf 用法: char ex[5]; gets_s(ex); 相当于 scanf("%s", ex); // 一旦输入超过4字节(末尾的'\0'占去1字节)就会出错 2. fgets是gets_s和scanf的改进。 用法: fgets(ex, 5, stdin); ...
  • ![![图片说明](https://img-ask.csdn.net/upload/201512/20/1450626035_108324.png)图片说明](https://img-ask.csdn.net/upload/201512/20/1450626028_454493.png)
  • s_gets函数的使用

    千次阅读 2017-10-21 21:07:29
    每次都无法独立写出来,...char * s_gets(char * st, int n) { char * ret_val; char * find; ret_val = fgets(st, n, stdin); if (ret_val) { find = strchr(st, '\n'); // look for newline if (find) // if
  • 请问vs2015环境下,使用gets函数报错,一定要用gets_s函数,怎么办?

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 73,936
精华内容 29,574
关键字:

gets_s函数

友情链接: gcutcls.rar