gets 订阅
gets从标准输入设备读字符串函数,其可以无限读取,不会判断上限,以回车结束读取,所以程序员应该确保buffer的空间足够大,以便在执行读操作时不发生溢出。 展开全文
gets从标准输入设备读字符串函数,其可以无限读取,不会判断上限,以回车结束读取,所以程序员应该确保buffer的空间足够大,以便在执行读操作时不发生溢出。
信息
原    型
char * gets ( char * str );
外文名
gets
头文件
stdio.h(c),cstdio(C++)
中文名
读取字符串
功    能
读取字符串
gets功能
从stdin流中读取字符串,直至接受到换行符或EOF时停止,并将读取的结果存放在buffer指针所指向的字符数组中。换行符不作为读取串的内容,读取的换行符被转换为‘\0’空字符,并由此来结束字符串。 [1] 
收起全文
精华内容
下载资源
问答
  • gets
    2021-12-27 15:07:31

    一、gets()函数

    在读取字符串时,scanf()和转换说明%s只能读取一个单词。可是在程序中经常要读取一整行输入,而不仅仅是一个单词。许多年前,gets()函数就用于处理这种情况。gets()函数简单易用,它读取整行输入,直至遇到换行符,然后丢弃换行符,储存其余字符,并在这些字符的末尾添加一个空字符使其成为一个 C 字符串。它经常和 puts()函数配对使用,该函数用于显示字符串,并在末尾添加换行符。

           /*程序1.1-- 使用 gets() 和 puts() */
    #include <stdio.h>
    #define LEN 30
    int main(void)
    {
    char words[LEN];
    gets(words); // 典型用法
    printf("Your string twice:\n");
    printf("%s\n", words);
    puts(words);
    return 0;
    }
    

    整行输入(除了换行符)都被储存在 words 中,gets()会丢弃换行符’\n’,但是puts()会在字符串末尾添加‘\n’,puts(words)和printf("%s\n,words")的效果相同。
    每次运行这个程序,编译器在输出中插入了一行警告消息。这是怎么回事?问题出在 gets()唯一的参数是 words,它无法检查数组是否装得下输入行。在gets()的参数中,数组名会被转换成该数组首元素的地址,因此,gets()函数只知道数组的开始处,并不知道数组中有多少个元素。
    如果输入的字符串过长,会导致缓冲区溢出(buffer overflow),即多余的字符超出了指定的目标空间。如果这些多余的字符只是占用了尚未使用的内存,就不会立即出现问题;如果它们擦写掉程序中的其他数据,会导致程序异常中止;或者还有其他情况(比如程序试图访问未分配的内存),有些人通过系统编程,利用gets()插入和运行一些破坏系统安全的代码。

    二、fget()函数(和fputs()函数)

    fgets()函数通过第2个参数限制读入的字符数来解决溢出的问题。该函数专门设计用于处理文件输入。
    fgets()和gets()的区别如下:
    1、fgets()函数的第2个参数指明了读入字符的最大数量。如果该参数的值是n,那么fgets()将读入n-1个字符,或者读到遇到的第一个换行符为止。
    2、如果fgets()读到一个换行符,会把它储存在字符串中。这点与gets()不同,gets()会丢弃换行符。
    3、fgets()函数的第3 个参数指明要读入的文件。如果读入从键盘输入的数据,则以stdin(标准输入)作为参数,该标识符定义在stdio.h中。

    因为 fgets()函数把换行符放在字符串的末尾(假设输入行不溢出),通常要与 fputs()函数(和puts()类似)配对使用,除非该函数不在字符串末尾添加换行符。fputs()函数的第2个参数指明它要写入的文件。如果要显示在计算机显示器上,应使用stdout(标准输出)作为该参数。

    /*程序2.1--- 使用 fgets() 和 fputs() */
    #include <stdio.h>
    #define LEN 10
    int main(void)
    {
    char words[LEN];
    fgets(words, LEN, stdin);
    printf("Your string twice (puts(), then fputs()):\n");
    puts(words);
    fputs(words, stdout);
    puts("Enter another string, please.");
    fgets(words, LEN, stdin);
    printf("Your string twice (puts(), then fputs()):\n");
    puts(words);
    fputs(words, stdout);
    return 0;
    }
    

    fputs()函数返回指向char的指针。如果一切进行顺利,该函数返回的地址与传入的第个参数相同。但是,如果函数读到文件结尾,它将返回一个(null pointer)特殊的指针:空指针,该指针保证不会指向有效的数据,所以可用于标识这种特殊情况。
    下面的程序2.2演示了一个简单的循环,读入并显示用户输入的内容,直到fgets()读到文件结尾或空行(即,首字符是换行符)。

    /*程序2.2-- 使用 fgets() 和 fputs() */
    #include <stdio.h>
    #define LEN 10
    int main(void)
    {
    char words[LEN];
    while (fgets(words, LEN, stdin) != NULL && words[0] != '\n')
    fputs(words, stdout);
    return 0;
    }
    

    下面是该程序的输出示例:

    123456789asdfghjklzxc
    123456789asdfghjklzxc
    

    有意思,虽然LEN被设置为10,但是该程序似乎在处理过长的输入时完全没问题。程序中的fgets()一次读入 LEN - 1 个字符(该例中为 9 个字符)。所以,一开始它只读入了“123456789”,并储存为123456789\0;接着fputs()打印该字符串,而且并未换行。然后while循环进入下一轮迭代,fgets()继续从剩余的输入中读入数据,即读入“asdfghjkl”并储存为asdfghjkl\0;接着fputs()在刚才打印字符串的这一行接着打印第 2 次读入的字符串。然后while 进入下一轮迭代,fgets()继续读取输入、fputs()打印字符串,这一过程循环进行,直到读入最后的“zxc\n”。fgets()将其储存为zxc\n\0, fputs()打印该字符串,由于字符串中的\n,光标被移至下一行开始处。
    程序2.3在程序2.2的基础上添加了一部分测试代码。该程序读取输入行,删除储存在字符串中的换行符,如果没有换行符,则丢弃数组装不下的字符。

    /* 程序2.3 -- 使用 fgets() */
    #include <stdio.h>
    #define LEN 10
    int main(void)
    {
    char words[LEN];
    int i;
    while (fgets(words, LEN, stdin) != NULL && words[0] != '\n')
    {
    i = 0;
    while (words[i] != '\n' && words[i] != '\0')
    i++;
    if (words[i] == '\n')
    words[i] = '\0';
    else // 如果word[i] == '\0'则执行这部分代码
    while (getchar() != '\n')
    continue;
    puts(words);
    }
    return 0;
    }
    

    循环while (words[i] != ‘\n’ && words[i] != ‘\0’)
    i++;
    遍历字符串,直至遇到换行符或空字符。如果先遇到换行符,下面的if语句就将其替换成空字符;如果先遇到空字符,else部分便丢弃输入行的剩余字符。下面是该程序的输出示例:

    This
    This
    program seems
    program s
    unwilling to accept long lines.
    unwilling
    

    三、空字符和空指针

    程序中出现了空字符和空指针。从概念上看,两者完全不同。空字符(或’\0’)是用于标记C字符串末尾的字符,其对应字符编码是0。由于其他字符的编码不可能是 0,所以不可能是字符串的一部分。空指针(或NULL)有一个值,该值不会与任何数据的有效地址对应。通常,函数使用它返回一个有效地址表示某些特殊情况发生,例如遇到文件结尾或未能按预期执行。空字符是整数类型,而空指针是指针类型。两者有时容易混淆的原因是:它们都可以用数值0来表示。但是,从概念上看,两者是不同类型的0。
    另外,空字符是一个字符,占1字节;而空指针是一个地址,通常占4字节。

    四、gets_s()函数

    gets_s()函数和fgets()类似,用一个参数限制读入的字符数。假设把下面的代码将把一行输入中的前9个字符读入words数组中,假设末尾有换行符:
    gets_s(words, LEN);
    gets_s()与fgets()的区别如下:
    1、gets_s()只从标准输入中读取数据,所以不需要第3个参数。
    2、如果gets_s()读到换行符,会丢弃它而不是储存它(和gets()函数一样)。
    3、如果gets_s()读到最大字符数都没有读到换行符,会执行以下几步。首先把目标数组中的首字符设置为空字符,读取并丢弃随后的输入直至读到换行符或文件结尾,然后返回空指针。接着,调用依赖实现的“处理函数”(或你选择的其他函数),可能会中止或退出程序。

    第2个特性说明,只要输入行未超过最大字符数,gets_s()和gets()几乎一样,完全可以用gets_s()替换gets()。第3个特性说明,要使用这个函数还需要进一步学习。
    **

    五、总结

    **
    我们来比较一下 gets()、fgets()和 gets_s()的适用性。如果目标存储区装得下输入行,3 个函数都没问题。但是fgets()会保留输入末尾的换行符作为字符串的一部分,要编写额外的代码将其替换成空字符。
    如果输入行太长会怎样?使用gets()不安全,它会擦写现有数据,存在安全隐患。gets_s()函数很安全,但是,如果并不希望程序中止或退出,就要知道如何编写特殊的“处理函数”。另外,如果打算让程序继续运行,gets_s()会丢弃该输入行的其余字符,无论你是否需要。由此可见,当输入太长,超过数组可容纳的字符数时,fgets()函数最容易使用,而且可以选择不同的处理方式。如果要让程序继续使用输入行中超出的字符,可以参考程序2.2中的处理方法。如果想丢弃输入行的超出字符,可以参考程序2.3中的处理方法。
    所以,当输入与预期不符时,gets_s()完全没有fgets()函数方便、灵活。也许这也是gets_s()只作为C库的可选扩展的原因之一。鉴于此,fgets()通常是处理类似情况的最佳选择。

    更多相关内容
  • gets()函数从标准输入(键盘)读入一行数据,所谓读取一行,就是遇到换行符就返回。gets()函数并不读取换行符’\n’,它会吧换行符替换成空字符’\0′,作为c语言字符串结束的标志。 gets()函数经常和puts()函数配对...
  • 最近在Linux下编译C语言,用到gets这个函数,代码如下: #include #include #include void main(){ char s[100]; // 存放输入的字符串 int i, j, n; printf(输入字符串:); gets(s); n=strlen(s); for(i=0,j=n-1...
  • 1.scanf(“%s”,str)和gets(str) scanf(“%s”,str)和gets(str)均可用于输入字符串到字符数组变量str,但scanf(“%s”,str)只读到输入字符的空格或回车处,而gets(str)读到回车处结束,所以当句子中单词由空格分开时...
  • scanf( )函数和gets( )函数都可用于输入字符串,但在功能上有区别。若想从键盘上输入字符串hi hello,则应该使用__gets__函数。  gets可以接收空格;而scanf遇到空格、回车和Tab键都会认为输入结束,所有它不能...
  • 主要介绍了C语言的getc()函数和gets()函数的使用对比,从数据流中一个是读取字符一个是读取字符串,需要的朋友可以参考下
  • 今天小编就为大家分享一篇c语言获取用户输入字符串是scanf和gets的区别详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • Winner-gets-all

    2021-03-27 16:32:39
    世界高尔夫协会工作流程
  • 主要介绍了C++中getline()、gets()等函数的用法,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
  • test_getsn

    2019-10-15 16:08:23
    鉴权
  • 使用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语言初学者。

    展开全文
  • 每当讨论 gets 函数时,大家不由自主地就会想起 1988 年的“互联网蠕虫”,它在 UNIX 操作系统的 finger 后台程序中使用一个 gets 调用作为它的攻击方式之一。很显然,对蠕虫病毒的实现来说, gets 函数的功劳不可...

    b561788dffd221f21578d62f912727ab.png

    每当讨论 gets 函数时,大家不由自主地就会想起 1988 年的“互联网蠕虫”,它在 UNIX 操作系统的 finger 后台程序中使用一个 gets 调用作为它的攻击方式之一。很显然,对蠕虫病毒的实现来说, gets 函数的功劳不可小视。不仅如此,GCC 也不推荐使用gets和puts函数。

    那么,究竟是什么原因导致 gets 函数这么不招人待见呢?

    正确的语句是d (int)k%m28. 不能进行++和--运算的数据类型为d 指针b)整型c) 长整型d) 常量 name:29. putchar函数可以向终端输出一个d 整型变量表达式b)实型变量值 字符串d)字符或字符型变量值 30. printf函数中用到格式符%5s,其中数字5表示输出的字 符串占用5列。gets函数功能:从键盘上输入字符,直至接受到换行符或eof时停止,并将读取的结果存放在buffer指针所指向的字符数组中。这次我输入了zhang和回车换行,fgets函数依然是读取5个字符(len-1个),这时fgets()读入zhang,已经是五个字符了,所以回车换行并不会读入,最后fgets()添加字符串结束标志'\0',所以我们看到输出时,press any...并没有换行输出,而是和zhang在同一行。

    4bf8a58db4da482f552000a3.gif

    该函数为在栈中分配size个字节的内存空间, 函数返回时会自动释放该空间. 成功返回指针, 失败返回null.。定义目录结构信息结构体dirent对象指针pdirent,之后通过一个while循环,该循环内通过调用readdir函数,以读取打开的目录对应的操作返回结果判断为条件。首先,next是一个指针,它指向一个函数,该函数返回另一个指针,该指针指向一个类型为char的常量指针,或者说next是一个指向函数的指针,该函数返回另一个指针,该指针指向一个只读的指向char的指针。

    如果函数的调用者提供了一个指向堆栈的指针,并且 gets 函数读入的字符数量超过了缓冲区的空间(即发生溢出),gets 函数会将多出来的字符继续写入堆栈中,这样就覆盖了堆栈中原来的内容,破坏一个或多个不相关变量的值。如下面的示例代码所示:

    int main(void)

    {

    char buffer[11];

    gets(buffer);

    printf("输出: %s\n",buffer);

    return 0;

    }示例代码的运行结果为:

    f6a2d8c327322b0c6714682c8e59d9d1.png

    aaa

    输出: aaa

    根据运行结果,当用户在键盘上输入的字符个数大于缓冲区 buffer 的最大界限时,gets 函数也不会对其进行任何检查,因此我们可以将恶意代码多出来的数据写入堆栈。由此可见,gets 函数是极其不安全的,可能成为病毒的入口,因为 gets 函数没有限制输入的字符串长度。所以我们应该使用 fgets 函数来替换 gets 函数,实际上这也是大多程序员所推荐的做法。

    1ddac4e1f3a0a16b740dcc969d96ed22.png

    相对于 gets 函数,fgets 函数最大的改进就是能够读取指定大小的数据,从而避免 gets 函数从 stdin 接收字符串而不检查它所复制的缓冲区空间大小导致的缓存溢出问题。当然,fgets 函数主要是为文件 I/O 而设计的(注意,不能用 fgets 函数读取二进制文件,因为 fgets 函数会把二进制文件当成文本文件来处理,这势必会产生乱码等不必要的麻烦)。其中,fgets 函数的原型如下:

    fgets函数功能:从文件指针stream中读取字符,存到以s为起始地址的空间里,知道读完n-1个字符,或者读完一行。函数说明 fgets()用来从参数stream所指的文件内读入字符并存到参数s所指的内存空间,直到出现换行字符、读到文件尾或是已读了size-1个字符为止,最后会加上null作为字符串结束。空语句和复合语句27413.3.2控制语句27513.3.3跳转语句27613.3.4关于分号的说明276习题13276第14单元函数28014.1函数参数28014.1.1现代c语言函数参数不能空28014.1.2c语言函数调用中的值结合28014.1.3指针类型参数28214.2函数定义与函数声明28914.2.1函数定义28914.2.2函数声明29014.3内联函数29114.3.1内联函数的概念29114.3.2c99的内联函数定义29114.3.3gcc的内联函数定义29214.3.4内联函数的限制292习题14292第15单元输入/输出29715.1格式化输出函数printf29715.1.1printf格式参数结构29715.1.2printf基本格式符29715.1.3长度修饰符29815.1.4域宽与精度说明29915.1.5前缀修饰符29915.2格式化输入函数scanf30115.2.1scanf指针参数30115.2.2scanf格式参数结构30215.2.3数值数据的输入控制30415.2.4scanf与输入缓冲区30515.2.5字符型数据的输入控制30615.2.6scanf的停止与返回30915.3c语言的文件操作31015.3.1文件及其分类31015.3.2file类型及其指针31215.3.3c语言文件操作的一般过程31315.3.4文件操作程序示例316习题15318附录324附录ac语言关键字324附录bc语言运算符的优先级和结合方向324附录c编译预处理命令325c.1宏定义325c.2文件包含326c.3条件编译326附录dc标准库头文件326附录ec语言常用标准库函数327e.1数学函数327e.2字符函数和字符串函数328e.3输入/输出函数329e.4动态内存分配函数331e.5退出程序函数331e.6数值转换函数331e.7时间和日期函数332参考文献333。

    与 gets 函数不同的是,如果 fgets 函数读到换行符,就会把它存储到字符串中,而不是像 gets 函数那样丢弃它。即给定参数 n,fgets 函数只能读取 n-1 个字符(包括换行符)。如果有一行超过 n-1 个字符,那么 fgets 函数将返回一个不完整的行(只读取该行的前 n-1 个字符)。但是,缓冲区总是以 null('\0') 字符结尾,对 fgets 函数的下一次调用会继续读取该行fgets读取一行。

    0_1286093885j2Ur.gif

    字符数组中一个元素只能存放一个字符,如 char a:表示定义了一个一维字符数组a,可存放5个字符,或存放最大长度为4的1个字符串(最后一个字符是字符串结束符‘\0’)。也就是说,后续的getchat()调用不会等待用户按键,而是直接读取缓冲区中的字符,直到缓冲区的字符读取完毕后,才等待用户按键。这里情况比较复杂的是scanf()函数,如果是scanf("%d",&a),它会忽略输入的空白符(换行,制表,空格)直到遇见非空白字符,再将其转换成整型存储在a中,注意,由于i/o缓冲,用来刷新输入缓冲的换行符还在等待被输入接受,此时能用getchar()捕获,但是在非空字符前面被忽略的空白符却因为被scanf()丢弃,已经不存在了。

    最后,它还需要第 3 个参数来说明读取哪个文件。如果是从键盘上读入数据,可以使用 stdin 作为该参数,如下面的代码所示:

    int main(void)

    {

    char buffer[11];

    fgets(buffer,11,stdin);

    printf("输出: %s\n",buffer);

    return 0;

    }对于上面的示例代码,如果输入的字符串小于或等于 10 个字符,那么程序将完整地输出结果;如果输入的字符串大于 10 个字符,那么程序将截断输入的字符串,最后只输出前 10 个字符。示例代码运行结果为:

    aaaaaaaaaaaaaaaa

    输出: aaaaaaaaaa

    除此之外,C99 还提供了 fgets 函数的宽字符版本 fgetws 函数,其函数的一般原型如下面的代码所示:

    该函数的功能与 fgets 函数一样。

    本文来自电脑杂谈,转载请注明本文网址:

    http://www.pc-fly.com/a/jisuanjixue/article-101477-1.html

    展开全文
  • gets 函数与 gets 函数都用于从标准输入流中读取行字符串保存,*str 是一个指向字符数组的指针,为输入字符串的存储位置。与 gets 函数不同, ge
  • C语言中scanf和gets

    2022-03-16 14:39:02
    目录scanf()的说明和使用gets()的说明和使用scanf("%s")和gets()的区别关于~和EOF scanf()的说明和使用 scanf(完成函数为int scanf(const char *format, …))属于库函数<stdio.h>,函数从标准输入流 stdin ...

    scanf()的说明和使用

    scanf(完成函数为int scanf(const char *format, …))属于库函数<stdio.h>,函数从标准输入流 stdin 读取输入,并根据提供的 format 来浏览输入,format 可以是一个简单的常量字符串,你也可以使用 %s、%d、%c、%f 等来指定读取字符串、整数、字符或浮点数。例如:

    #include <iostream>
    #include <cstdio>
    #include <stdio.h>
    
    int main(){
        int n=0;
        char c,str[10];
        scanf("%d %c %s",&n,&c,&str);
        printf("%d %c %s",n,c,str);
        return 0;
    }
    

    输入为: 23 A abcd(每次输入后都回车)      输出为: 23 A abcd    一切正常
    在这里插入图片描述
    但是如果我这样写:

    #include <iostream>
    #include <cstdio>
    #include <stdio.h>
    
    int main(){
        int n=0;
        char c,str[10];
        scanf("%d",&n);
        scanf("%c",&c);
        scanf("%s",&str);
       // scanf("%d %c %s",&n,&c,&str);
    
       // printf("%d %c %s",n,c,str);
       printf("n=:%d\n",n);
       printf("c=:%c\n",c);
       printf("str=:%s\n",str);
        return 0;
    }
    

    还是原样,输入为: 23 A abcd(每次输入后都回车)
    这个时候的输出为:23    A(程序在我输入A以后就结束了,并没有给我输入abcd的机会)
    在这里插入图片描述
    仔细观察输出你就会发现,c的值看似是null,但其实是我们输入的回车,这点可以用输出ASCII码来验证,修改c的输出

    #include <iostream>
    #include <cstdio>
    #include <stdio.h>
    
    int main(){
        int n=0;
    
        char c,str[10];
    
        scanf("%d",&n);
        scanf("%c",&c);
        scanf("%s",&str);
       // scanf("%d %c %s",&n,&c,&str);
    
       // printf("%d %c %s",n,c,str);
       printf("n=:%d\n",n);
       printf("c=:%d\n",c);
       printf("str=:%s\n",str);
        return 0;
    }
    

    同样的输入,结果为:
    在这里插入图片描述
    PS:10为换行/新行的十进制ASCII码,也就是说scanf中的%c会吃回车,经测试%s并不会,在这里可以使用getchar()来抢先吃掉回车,代码为:

    #include <iostream>
    #include <cstdio>
    #include <stdio.h>
    
    int main(){
        int n=0;
        char c,str[10];
        scanf("%d",&n);
        getchar();//新加了这个来吃掉输入结束后敲得回车
        scanf("%c",&c);
        scanf("%s",&str);
       // scanf("%d %c %s",&n,&c,&str);
    
       // printf("%d %c %s",n,c,str);
       printf("n=:%d\n",n);
       printf("c=:%d\n",c);
       printf("str=:%s\n",str);
        return 0;
    }
    

    在这里插入图片描述
    scanf还可以使用%f,%lf来分别读取单精度浮点数(float)和双精度浮点数(double),用法和%d相同。
    scanf返回值问题:
    scanf有三种返回值,分别是:
       正整数:代表输入赋值成功,正整数为赋值成功变量的数量
           零:   0表示输入异常,一般指输入错误的数据类型,要整数你偏给字符
           -1:   -1表示输入流结束,可以使用scanf()!= -1来判断输入是否结束,自己测试的时候可以用Ctrl+Z结束输入

    #include <iostream>
    #include <cstdio>
    #include <stdio.h>
    
    int main(){
        int n1=0,n2=0,n3=0,n4=0,m=0,k=0,a,b;
        n1 = scanf("%d",&m);
        n2 = scanf("%d %d",&a,&b);
        n3 = scanf("%d",&k);
        printf("m=:%d\n",m);
        printf("a=:%d\n",a);
        printf("b=:%d\n",b);
        printf("n1=:%d\n",n1);
        printf("n2=:%d\n",n2);
        printf("n3=:%d\n",n3);
        printf("n4=:%d\n",n4);
    
       return 0;
    }
    

    在这里插入图片描述

    gets()的说明和使用

    char *gets(char *str)函数的功能是从输入缓冲区中读取一个字符串存储到变量 str 所指向的内存空间,str 可以是一个字符指针变量名,也可以是一个字符数组名

    #include <iostream>
    #include <cstdio>
    #include <stdio.h>
    
    int main(){
        char str1[10];
        gets(str1);
        printf("str1=: %s",str1);
       return 0;
    }
    

    在这里插入图片描述

    scanf("%s")和gets()的区别

    先说结论:

    scanf("%s")遇到空格会停,gets()遇到空格不停,会把空格读走,并且作为一个元素,放在字符数组中。
    scanf("%s")不读取回车,输入结束时敲得那个回车scanf("%s")不要,也不会读走,而是留在缓冲区给下一个“有缘人”。gets()读取回车,并且以读取到回车作为结束标志,scanf("%s")结束的依据是输入流是否为空或者返回值是否等于变量数,即括号的内的变量是否都已经赋值完成。

    #include <iostream>
    #include <cstdio>
    #include <stdio.h>
    
    int main(){
        char str1[10],str2[10];
        scanf("%s",&str1);
        scanf("%s",&str2);
        // gets(str1);
        //gets(str2);
        printf("str1=: %s\n",str1);
        printf("str2=: %s",str2);
       return 0;
    }
    

    在这里插入图片描述
    啥也不输入直接狂按回车,没有任何反应。
    在这里插入图片描述

    gets()遇到空格不停,会把空格读走,并且作为一个元素,放在字符数组中。

    #include <iostream>
    #include <cstdio>
    #include <stdio.h>
    
    int main(){
        char str1[10],str2[10];
       // scanf("%s",&str1);
       // scanf("%s",&str2);
        gets(str1);
        gets(str2);
        printf("str1=: %s\n",str1);
        printf("str2=: %s",str2);
    
       return 0;
    }
    

    在这里插入图片描述
    gets()遇到回车会结束输入(这里啥都没输,直接敲了两个回车)
    在这里插入图片描述
    scanf()结束看返回值,即变量是否全部赋值完成

    #include <iostream>
    #include <cstdio>
    #include <stdio.h>
    
    int main(){
        char str1[10],str2[10];
    
        scanf("%s %s",&str1,&str2);
        //scanf("%s",&str2);
        //gets(str1);
        //gets(str2);
        printf("str1=: %s\n",str1);
        printf("str2=: %s",str2);
    
       return 0;
    }
    

    在这里插入图片描述
    这里第一个abcd被str1读走,但是str2还没有成功赋值,所以即使我狂敲回车,scanf依然不会放弃str2,知道我再次输入abcd,赋值给str2,输入结束

    关于~和EOF

    #关于~的作用
           在Windows下,用户按下Ctrl+Z(会看到一个^Z字符),会停止输入流,scanf会返回-1。-1的补码为11111111 11111111 11111111 11111111 一共4个字节。~是C语言中的按位取反,
    ~(-1)结果为00000000 00000000 00000000 00000000刚好为整数0的补码。
    因此当输入Ctrl+Z时,scanf会返回-1,while(~-1)==while(0),0为假,退出while循环。

    #EOF

            在C语言中,或更精确地说成C标准函数库中表示文件结束符(end of file)。在while循环中以EOF作为文件结束标志,这种以EOF作为文件结束标志的文件,必须是文本文件。在文本文件中,数据都是以字符的ASCII代码值的形式存放。我们知道,ASCII代码值的范围是0~127,不可能出现-1,因此可以用EOF作为文件结束标志,例如

    #include <stdio.h>
    int main(void)
    {
    int n,i;
    int array[25];
    while(scanf("%d",&n)!=EOF)
    {
    for (i=0; i<n; i++)
    scanf("%d",&array[i]);
    for (i=0; i<n; i++)
    printf ("%d ",array[i]);
    }
    return 0;
    }
    

    ————————————————
    ~部分解释源自CSDN博主「saysine2020」的原创文章
    原文链接:https://blog.csdn.net/zys_shan/article/details/104393211
    EOF部分源自百度百科
    原文链接:https://baike.baidu.com/item/EOF/1017800?fr=aladdin

    展开全文
  • gets函数,C语言gets函数详解

    千次阅读 多人点赞 2021-08-24 14:17:35
    gets函数,C语言gets函数详解 在前面从键盘输入字符串是使用 scanf 和 %s。其实还有更简单的方法,即使用 gets() 函数。该函数的原型为: # include <stdio.h> char *gets(char *str); 这个函数很简单,只有...
  • GETS_App_binder

    2021-04-03 06:14:18
    GETS_App:AplicaçãoWeb paraAnálise达多斯州临时GETS(使用mybinder)nd迪斯DescriçãoGeral 视障人士使用的医院资料和服务的代办处,以及国立卫生技术服务局(GETS)的国立医疗服务局(TESS)的医疗服务和服务...
  • gets()函数

    2022-06-27 14:22:30
    gets()函数
  • ruby-gets-input-v-000

    2021-02-21 09:50:34
    gets CLI输入目标了解在CLI应用程序中捕获和操作用户输入的重要性。 在CLI中创建用于用户输入的提示。 使用#gets方法捕获,存储该输入并对其进行操作。用户输入和CLI 我认为可以说个人计算机已经成为我们创造的最...
  • gets,fgets,gets_s的区别分析

    千次阅读 多人点赞 2020-08-07 15:48:45
    在最开始学习字符串时,我们最常用的输入字符串函数就是——gets(); 这个函数将输入缓冲区中的数据存储到字符型数组中,以换行符结束,并丢弃末尾的换行符添加一个空字符。他解决了scanf("%s",str);以空白符为截至的...
  • ①getsc++【1】函数:gets(字符指针)程序员【2】头文件:stdio.h(c中),c++不需包含此头文件数组【3】原型:char*gets(char*buffer);函数【4】功能:从stdin流中读取字符串,直至接受到换行符或EOF时中止,并将读取...
  • gets CLI输入 目标 了解在CLI应用程序中捕获和操作用户输入的重要性。 在CLI中创建用于用户输入的提示。 使用#gets方法捕获,存储该输入并对其进行操作。 用户输入和CLI 我认为可以说个人计算机已经成为我们创造...
  • ruby-gets-input-cb-gh-000

    2021-02-24 02:04:17
    gets CLI输入目标了解在CLI应用程序中捕获和操作用户输入的重要性。 在CLI中创建提示用户输入的提示。 使用#gets方法捕获,存储该输入并对其进行操作。用户输入和CLI 我认为可以说个人计算机已经成为我们创造的最...
  • gets()、fgets()、gets_s()、s_gets()

    千次阅读 2020-09-10 10:40:13
    gets()、fgets()、gets_s()、s_gets() 1、gets()
  • 原因是gets函数在获取键盘输入时不会判断目标的空间,会造成越界,因此编译器报错提示这是不安全的函数。此时可用fgets函数代替。
  • C语言 scanf()和gets()函数的区别1.相同点:scanf( )函数和gets( )函数都可用于输入字符串2.不同点:两者在功能上有所区别,具体区别如下:要实现如下需求“从控制台输入字符串”有如下两种实现方式:1>使用gets()...
  • gets和puts函数

    2021-10-30 17:11:33
    gets和puts函数 笔记来源于王道C语言训练营 1.gets函数(只能读取字符串) scanf在读取字符串时,当遇到空格后,就会匹配结束,这样没办法把一行带有空格字符串存入到一个存入到一个字符数组,由此引出 gets 函数 当...
  • (其实不知道写什么第一代 gets(函数首先呢,gets()函数简单易用,它读取整行输入,直至遇到换行符(\n,然后丢弃换行符,储存其余字符,并这些字符的末尾添加一个空字符 使其成为一个 C 字符串。它经常和 puts()函数...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 321,633
精华内容 128,653
关键字:

gets

友情链接: cbf.zip