首页 > 其他分享 >字符串和字符串函数(二)

字符串和字符串函数(二)

时间:2023-03-02 22:32:36浏览次数:41  
标签:函数 s1 空字符 char 字符串 gets

2.字符串输入

如果要把一个字符串读入程序,必须先预留存储该字符串的空间,然后用输入函数获取该字符串。

2.1分配空间

预先分配空间则意味着必须为字符串分配足够使用的空间大小,你可能写过​​char *name; scanf("%s", name);​​​,虽然可能编译器会通过,但是会给出警告,因为scanf函数将信息拷贝至参数指定的地址上,而此时参数是一个未被初始化的指针,name可能会指向任何地方,则可能会擦除程序中的数据或代码,从而导致程序异常终止。最简单的分配空间方式,就是显示指明数组的大小​​char name[81];​​,还有一种方式则是通过C库函数来分配内存。

2.2gets()函数(C11标准已废除)

在为字符串分配空间之后,便可读入字符串,除了前面介绍的scanf()函数,我们再了解两个读取字符串的函数:fgets()函数和gets()函数。

在读取字符串时,scanf函数和%s转换说明只能读取一个单词,因为scanf函数除了%c转换说明,都以空白符作为输入隔断。但通常我们需要整行读入,在过去gets()函数用来处理这种情况,gets函数简单易用,它读取整行输入,直至遇到换行符,然后丢弃换行符,存储其余字符,并在这些字符结尾加入一个空字符使其成为一个C字符串。它经常和puts()函数配对使用,puts函数用于显示字符串,并在末尾添加换行符。

但是puts()函数有一个十分要命的缺点,gets()函数只知道数组的开始处,并不知道数组到哪结束。如果输入的字符串过长,会导致缓冲区溢出,即多余的字符超出了指定的目标空间。如果这些多余的字符只是占用了已分配的尚未使用的内存,并不会立即引起很严重的影响,但是如果它们擦写掉了程序中的数据或代码,会导致程序异常终止,因此,在过去很多人利用该函数插入和运行一些破坏系统安全的代码。虽然目前C标准已经废除了gets函数,但是不少编译器为了兼容以前的代码,大部分选择继续支持gets函数,因为只要gets函数使用得当,它的确是一个很方便的函数。

2.3gets()的替代品
2.3.1 fgets()函数

fgets()函数通过第二个参数限制读入字符数来解决溢出的问题。该函数专门设计用于处理文件输入,fgets()函数与gets()函数的区别:1.fgets函数有第二个参数限制读入字符串的最大长度。如果参数是n,则fgets函数最多读入n-1个字符,或者遇到第一个换行符。2.如果fgets函数遇到一个换行符,会把它存储到字符串当中,而gets函数不会。3.fgets函数的第三个参数指明要读入的文件。如果读入从键盘输入的数据,则以stdin作为参数,该标识符定义在stdio.h中。

因为fgets把换行符读入,通常与fputs()函数一起使用,fputs函数的第二个参数指明它要写入的文件。如果要显示在计算机的显示器上,使用stdout作为该参数。

2.3.2 gets_s()函数

C11新增的gets_s()函数与fgets()函数类似,用一个参数限制读入的字符数。但是gets_s函数只从标准输入(stdin)读取数据,所以不需要第三个参数;gets_s函数读到换行符时,会丢弃它而不是存储它;如果gets_s函数读到最大字符数都没有读到换行符,会执行一下几步:首先把目标数组的首字符设置为空字符,读取并丢弃随后的输入直至读到换行符或者文件结尾,然后返回空指针,接着调用依赖实现的“处理函数”,可能终止或退出函数。

3.字符串输出

3.1puts()函数

puts函数很容易使用,只需把字符串的地址作为参数传递给它即可,如指针、数组名、字符串常量等。puts函数在现实字符串时会自动在其末尾添加一个换行符,puts在遇到空字符时就停止输出。因此千万不要用puts函数输出输出一个普通的char数组。

3.2fputs()函数

fputs函数是puts函数针对文件定制的版本。它们之间的区别就是,fputs的第二个参数指明要写入数据的文件,并且fputs函数不会在输出的末尾添加换行符。

4.字符串函数

C库提供了多个处理字符串的函数,ANSI C把这些函数的原型放在string.h头文件中。

4.1strlen()函数

​int strlen(const char* s);​​返回字符串s的字符数,末尾的空字符除外。

4.2strcat()函数

​char *strcat(char *restrict s1, const char *restrict s2);​​把s2指向的字符串拷贝s1指向的字符串,s2指向的字符串第一个字符覆盖s1指向的字符串的空字符,并且该函数返回s1。

4.3strncat()函数

​char *strncat(char *restrict s1, const char *restrict s2, size_t n);​​与strcat函数类似,只不过strncat是将s2指向的第二个字符串的n个字符拷贝到第一个字符串,或者拷贝到遇到空字符。这是因为strcat函数无法检查第一个数组能否容纳第二个字符串,这就可能造成与gets函数相同的问题,于是通过strncat函数的第三个参数来限定最大拷贝字符数。

4.4strcmp()函数

​int strcmp(const char *s1, const char *s2);​​比较s1和s2指向的两个字符串。如果完全匹配,则两字符串相同,否则比较首次出现不匹配的字符对。通过字符编码值比较字符,如果两字符串相同,函数返回0;如果第一个字符串小于第二个字符串,函数返回小于0的值;如果第一个字符串大于第二个字符串,函数返回大于0的值。

4.5strncmp()函数

​int strcmp(const char *s1, const char *s2, size_t n);​​strncmp也与strcmp类似,strncmp函数只比较前n个字符,或者比较到第一个空字符为止。如何返回值与strcmp函数相同。

4.6strcpy()函数strncpy()函数

​char *strcpy(char *restrict s1, const char *restrict s2);​​​把s2指向的字符串拷贝到s1指向的位置,函数返回s1。​​char *strcpy(char *restrict s1, const char *restrict s2, size_t n);​​把s2指向的字符串的n个字符拷贝s1指向的位置,如果在拷贝到n个字符之前遇到空字符,则后面补充若干个空字符,使其长度为n;若拷贝n个字符并且没有遇到空字符,则不添加空字符,函数返回s1。

前面提过,指针表示法只是拷贝指向字符串的地址,而数组表示法则是拷贝的字符串副本。现在我们能够通过strcpy函数来拷贝整个字符串,拷贝出来的字符串被称为目标字符串,最初的字符串被称为源字符串。同时,第一个参数不必指向数组的开始。但是strcpy函数和strcat函数有相同的问题,它们都不能检查目标空间是否能容纳源字符串的副本。所以。拷贝字符串用strncpy函数更安全,根据strncpy函数的介绍,如果目标空间装不下副本,则可能导致字符串中不含空字符,因此需要将副本的最后一个元素设置为空字符,以确保存储的是一个字符串。

前面提到函数参数可以灵活声明为指针、数组和字符串常量,但是声明数组将分配存储空间,而声明指针只需要分配存储一个地址的空间。

4.7sprintf()函数

sprintf()函数声明在stdio.h中,而不是string.h头文件中。该函数与printf函数类似,但是它是把数据写入字符串,而不是打印在显示器上,因此该函数可以把很多个元素组合成一个字符串。sprintf()的第一个参数是目标字符串的地址,其余参数和printf()相同,即格式化字符串和待写入项的列表。








标签:函数,s1,空字符,char,字符串,gets
From: https://blog.51cto.com/u_15944236/6096812

相关文章

  • 345. 反转字符串中的元音字母
    编写一个函数,以字符串作为输入,反转该字符串中的元音字母。 示例1:输入:"hello"输出:"holle"示例2:输入:"leetcode"输出:"leotcede"     classSolution......
  • 680. 验证回文字符串 Ⅱ
    给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。示例1:输入:"aba"输出:True示例2:输入:"abca"输出:True解释:你可以删除c字符。 ......
  • c# 判断字符串是否为空的效率问题
    循环1000000000次,stringa="100";stringb="200";for(inti=0;i<1000000000;i++)      {        if(string.Is......
  • leetcode 2564. 子字符串异或查询[题解]
    链接:子字符串异或查询思路:题目说\(val\oplusfirst=second\)可得\(val=second\oplusfirst\)题目变成从\(0-1\)串中找到最先出现的\(val\)的二进制表示,注意是\(10^......
  • LEETCODE 面试题 05.02. 二进制数转字符串
    每次将实数乘2,取出最高位的部分存到res里,实数乘2的结果再减去最高位进入下一次循环0.625-》1.25取出1加入res,1.25-》0.25》0.5,取出0加入res0.5-》1 取出1加入res,最终输入......
  • 找到字符串中的所有字母异位词
    找到字符串中的所有字母异位词给定两个字符串 s 和p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。异位词指由相同字母重......
  • 04-Go字符串、指针、结构体
    1字符串packagemain//字符串funcmain(){varastring="helloworld"//1按索引取值,只能取,不能改fmt.Println(a[0])//104utf-8对照......
  • KingbaseES函数三态
    理解函数的三态1VOLATILE:volatile函数没有限制,可以修改数据(如执行delete,insert,update),使用同样的参数调用可能返回不同的值.STABLE:不允许修改数据,PG8.0以......
  • jmeter日期时间函数:time函数
     time函数的使用方法:${__time(日期时间格式,自定义变量名)} 年:yyyy或yy  月:MM  日:dd  时:HH(24小时制) hh(12小时制)  分:mm  秒:ss  毫秒:SSS1.......
  • Python设置字符串颜色
    使用\033[3表示字体颜色,\033[4表示背景色。示例print("\033[31;1mhello")print("\033[32;1mhello")print("\033[33;1mhello")print("\033[34;1mhello")print("\033[3......