gets、fgets、gets_s、scanf函数学习总结

本文详细介绍了C语言中用于字符串输入的四个函数:gets()、fgets()、gets_s()和scanf()。讨论了它们的功能、使用场景及潜在的安全隐患,并通过示例展示了如何正确使用这些函数。

1、gets()函数:

a、读取整行输入输入,直至遇到换行符,然后丢弃换行符,在字符的结尾添加一个空字符使其成为一个C字符串(经常和puts()函数搭配使用-->显示字符串,并且在末尾添加换行符),对应a输入 

b、隐患:如果输入的字符过长,会导致缓冲区溢出,即多余的字符超出了指定的目标空间(对应b输入)
/*getsputs.c--使用gets()和puts()*/
#include <stdio.h>
#define STLEN 81
int main(void)
{
    char words[STLEN];

    puts("Enter a string,please.");
    gets(words);             //典型用法
    printf("Your string twice:\n");
    printf("%s\n",words);    //效果相同
    puts(words);             //同上
    puts("Done.");

    return 0;
}

/*****************************************
a输入
Enter a string,please.
I want to learn about string theory!
Your string twice:
I want to learn about string theory!
I want to learn about string theory!
Done.
*****************************************/

/****************************************
b输入
Enter a string,please.
warning:this program uses gets(),which is unsafe.
I think I'll be just fine.
Your string twice:
I think I'll be just fine. 
I think I'll be just fine.
Done.
Segmentation fault:11
****************************************/

2、fgets()函数:

a、第二个参数限制读入字符的最大数量,如果参数的值是n,那么fgets()将读入n-1个字符,或者读到遇到的第一个换行符为止

b、读取到一个换行符,会将其储存在字符串中

c、fgets()的第三个参数指明要读入的文件,如果从键盘输入数据,则以stdin(标准输入)作为参数,该标识符定义在stdio.h中(fgets()函数通常和fputs()函数使用,该函数不在字符串末尾添加换行符,如果要显示在屏幕上,则使用stdout作为参数)
/*fgetsl.c--使用fgets()和fputs()*/
#include <stdio.h>
#define STLEN 14
int main(void)
{
    char words[STLEN];

    puts("Enter a string.please.");
    fgets(words,STLEN,stdin);
    printf("Your string twice(puts(),then fputs())\n");
    puts(words);
    fputs(words,stdout);
    puts("Enter another string,please.");
    fgets(words,STLEN,stdin);
    printf("Your string twice (puts(),then fputs()):\n");
    puts(words);
    fputs(words,stdout);
    puts("Done");

    return 0;
}

**************************************************
Enter a string.please.
apple tie
Your string twice(puts(),then fputs())
apple tie

apple tie
Enter another string,please.
strawberry shortcake
Your string twice (puts(),then fputs()):
strawberry sh
strawberry shDone
***************************************************

3、gets_s()函数:

a、只从标准输入中读取数据,无需第三个参数

b、如果读取到换行符,丢弃他而不是储存他

c、如果读取到最大字符数都未读取到换行符,会执行以下几步:目标数组首字符设置为空字符,读取并且丢弃随后的输入直至读到换行符或者文件结尾,然后返回空指针,接着调用依赖实现的"处理函数"

4、scanf()函数:

  从第一个非空白字符作为字符串的开始,如果使用%s转换说明,以下一个空白字符(空行,空格,制表符或者换行符)作为字符串的结束(字符串不包括空白字符),如果指定了字符宽度,如%10s,那么scanf()函数将读取10个字符或读到第1个空白字符停止(先满足的条件即是结束输入的条件)

 输入语句               原输入序列        name中的内容     剩余输入序列
scanf("%s",name);    Fleebert Hup        Fleebert            _Hup
scanf("%5s",name);   Fleebert Hup        Fleeb            ert Hu
scanf("%5s",name);     Ann Ular            Ann              _Ular 
/*scan_str.c--使用scanf()*/
#include <stdio.h>
int main(void)
{
    char name1[11],name2[11];
    int count;

    printf("Please enter 2 names.\n");
    count = scanf("%5s %10s",name1,name2);
    printf("I need the %d name %s and %s.\n",count,name1,name2);

    return 0;
}

/***************************************************
Please enter 2 names.
Jesse Jukes
I need the 2 name Jesse and Jukes.

Please enter 2 names.
Liza Applebottham
I need the 2 name Liza and Applebotth.

Please enter 2 names.
Portensia Callowit
I need the 2 name Porte and nsia.
***************************************************/
fgetsscanf是C语言中常用的输入函数,二者的区别如下: - **安全性**:fgets函数安全性高,可指定缓冲区大小,避免输入溢出;scanf函数在读取字符串时若使用`%s`格式说明符,不限制输入长度,易造成缓冲区溢出问题。例如使用`scanf("%s", buffer)`时,若用户输入的字符串长度超过`buffer`数组大小,就会产生溢出。而使用`fgets(buffer, sizeof(buffer), stdin)`,可指定最大读取长度,防止溢出[^2]。 - **对换行符的处理**:fgets函数会保留输入中的换行符,通常需手动移除;scanf函数在读取时会将换行符视为分隔符,不会将其存储到变量中。例如使用`fgets(buffer, sizeof(buffer), stdin)`读取输入后,若要移除换行符,可使用`buffer[strcspn(buffer, "\n")] = '\0'`;而`scanf("%s", buffer)`会自动跳过换行符等空白字符[^2]。 - **标准支持**:fgets函数被所有标准支持;gets函数在C11标准中已被移除,scanf函数则一直被广泛支持[^2]。 - **输入截断处理**:fgets函数会截断并保留剩余输入;scanf函数在读取字符串时无输入截断处理机制,若输入过长会直接溢出。例如使用fgets读取输入时,若输入过长,会将超出部分留在输入缓冲区,可通过检查`strlen(buffer) == sizeof(buffer)-1 && buffer[sizeof(buffer)-2] != '\n'`判断输入是否被截断,并使用`while (getchar() != '\n')`清空剩余输入;而scanf在读取字符串时无此处理机制[^2]。 - **适用场景**:fgets函数适用于所有需要安全读取字符串的场景;scanf函数适用于读取格式化输入,如读取整数、浮点数等,但在读取字符串时需谨慎使用。例如读取整数可使用`scanf("%d", &num)`,而读取字符串建议使用fgets函数[^2]。 - **对特殊字符的处理**:scanf函数使用`%s`读取字符串时,将空格、回车等空白字符视为字符串的结束;fgets函数会读取包括空格在内的整行输入,直到遇到换行符或达到指定的最大长度。例如使用`scanf("%s", buffer)`,若输入`hello world`,只会读取`hello`;而使用`fgets(buffer, sizeof(buffer), stdin)`会读取整行`hello world\n`(包含换行符)[^3]。 ### 代码示例 ```c #include <stdio.h> #include <string.h> int main() { // 使用fgets读取字符串 char buffer[100]; fgets(buffer, sizeof(buffer), stdin); buffer[strcspn(buffer, "\n")] = '\0'; // 移除换行符 printf("fgets读取的字符串: %s\n", buffer); // 使用scanf读取字符串 char name[10]; scanf("%9s", name); // 预留一个位置给字符串结束标志'\0' printf("scanf读取的字符串: %s\n", name); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值