服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C语言通过gets和gets_s分别实现读取含空格的字符串

C语言通过gets和gets_s分别实现读取含空格的字符串

2022-07-21 09:46ww171992 C/C++

在遇到包含空格的字符串输入时该如何读取呢?如果使用scanf以%s格式去读取输入的字符串,遇到空格就读取结束了,显然这样是读取不了的。本文就将介绍两个可以对含空格字符串读取的库函数------gets和gets_s函数,感兴趣的可以了

导读

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

gets函数

函数声明

char * gets ( char * str );

函数介绍

头文件

#include<stdio.h>

从stdin获取字符串

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

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

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

请注意,gets与fgets完全不同: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:多组输入含空格字符串,输出其字符串长度和字符串

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#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:使用动态内存分配函数返回的指针接收输入的含空格的字符串

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#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的最大大小(这里指内存空间大小)(这可能导致缓冲区溢出)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#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类型型数组存放

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#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:多组输入,多组输出,输入处理含空格的字符串,以动态内存分配函数形式

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#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时常会出现崩溃情况,我还是把题目放底下给大家吧。

C语言通过gets和gets_s分别实现读取含空格的字符串

到此这篇关于C语言通过gets和gets_s分别实现读取含空格的字符串的文章就介绍到这了,更多相关C语言读取含空格的字符串内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/m0_62080641/article/details/122011931

延伸 · 阅读

精彩推荐
  • C/C++VC实现获取当前正在运行的进程

    VC实现获取当前正在运行的进程

    这篇文章主要介绍了VC实现获取当前正在运行的进程,涉及VC针对系统进程的相关操作技巧,需要的朋友可以参考下 ...

    好人一个6212021-02-26
  • C/C++C++ 中的虚函数表及虚函数执行原理详解

    C++ 中的虚函数表及虚函数执行原理详解

    这篇文章主要介绍了C++ 中的虚函数表及虚函数执行原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    Er_HU8342021-10-26
  • C/C++C++判断子序列题目详解

    C++判断子序列题目详解

    这篇文章主要为大家介绍了C++判断子序列题目,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助...

    Listen attentively6752022-03-02
  • C/C++C++构造函数深度学习

    C++构造函数深度学习

    这篇文章主要为大家详细介绍了C++构造函数,深度学习C++构造函数,感兴趣的小伙伴们可以参考一下...

    郭小雷11332021-04-13
  • C/C++利用C++11原子量如何实现自旋锁详解

    利用C++11原子量如何实现自旋锁详解

    当自旋锁尝试获取锁时以忙等待(busy waiting)的形式不断地循环检查锁是否可用,下面这篇文章主要给大家介绍了关于利用C++11原子量如何实现自旋锁的相...

    兔晓侠5762021-06-26
  • C/C++一波C语言字符数组实用技巧集锦

    一波C语言字符数组实用技巧集锦

    这篇文章主要介绍了一波C语言字符数组实用技巧集锦,包括许多字符的转换与提取等基本操作示例,需要的朋友可以参考下...

    hzy377411062021-03-31
  • C/C++opencv3/C++绘制几何图形实例

    opencv3/C++绘制几何图形实例

    今天小编就为大家分享一篇opencv3/C++绘制几何图形实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    阿卡蒂奥10872021-08-08
  • C/C++C/C++中带空格字符串的输入讲解

    C/C++中带空格字符串的输入讲解

    这篇文章主要给大家介绍了关于如何解决C++中带空格字符串的输入问题,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧...

    zj_ahu5962021-12-29