IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 初学者对C语言的爱恨情仇之神秘的字符串 -> 正文阅读

[C++知识库]初学者对C语言的爱恨情仇之神秘的字符串

前言

本文是针对对字符串有疑惑的初学者。例如:对C语言中的字符串并不了解,不太会使用。学过其他编程语言,现在转入了C语言,但是在C语言中使用字符串时不能像Java一样如愿以偿,自由自在的使用。那么就可以看本篇文章,本篇文章不会涉及太深的东西,太深的东西对于初学者会受不了的。

字符串是谁

说到字符串是谁,那么需要提一下字符是什么,没有字符就没有字符串。

像我们学的“每一个”英文字符(a,b,c…)都是属于字符,并且汉字、数字、标点符号都是属于一个字符;

像“我是谁,我在哪”这7个字符合起来就是一个字符串。那么串的话其实就是多个字符合在一起的结果。

经常听说字符串字面量,究竟是什么鬼?

经常听别人说字符串字面量,字面量的这是啥呢?

其实你一点也磨陌生,可能只是对这个名字陌生一些,你在学习Hello World的时候,其实就在用了。没错用双引号包含的“Hello World”就是字符串字面量。

printf("Hello World!");

执行结果:

Hello World!

我们想换行时,可以加个\n:

printf("Hello  \n   World!");

结果:

Hello  
   World!

字符串字面量如何存储的

例如字符串:"Hello World!"

你看着是一个字符串,实际上在存储的时候,是像数组一样,一个字符一个字符分开存的。

[“H”,“e”,“l”,“l”,“o”," “,“W”,“o”,“r”,“l”,“d”,”!","\0"];

在存储的时候,每个字符串的结尾是包含"\0",所以一般我们如果不知道一个字符串的长度如何遍历每个字符呢?那就可以使用"\0"条件来判断。

C语言字符数组与字符指针

我们可以利用char类型的数组,来定义和初始化字符串。

char str[12] = "I Love You!";
char *pStr = "I Love You!";

我们在打印的时候,需要使用%s来格式化数值:

printf("str=%s\n",str);
printf("pStr=%s\n",pStr);

打印结果:

str=I Love You!
pStr=I Love You!

也支持多种单个访问方式:

printf("*(str+2)=%c\n",*(str+2));
printf("*(pStr+2)=%c\n",*(pStr+2));

结果:

*(str+2)=L
*(pStr+2)=L

C语言中的字符串库

在Java中有String类型的jar包,在C语言中也有相应的字符串库。无论是Java中的jar包,还是C语言中的库。其实都是一些封装好的工具,以便给他人使用。

在实际开发中,我们掌握这些库的基本用法是必须的,可以大大的提高我们的工作效率。

在Linux中我们可以使用man命令来查看帮助手册。

例如:

man string

会出现下面这样的结果:
在这里插入图片描述

可以看到:
在这里插入图片描述

这些都是我现在这个Ubuntu系统中的string库中所提供的一些功能的函数。

在此我带着熟悉几个常用的函数。

我挑选了几个常用的,其实也就四种:统计字符串中的字符个数、字符串拼接、字符串比较、字符串拷贝/赋值。

SYNOPSIS
       #include <string.h>

       size_t strlen(const char *s);
              Return the length of the string s.

       char *strcat(char *dest, const char *src);
              Append the string src to the string dest, returning a pointer dest.
              
       char *strncat(char *dest, const char *src, size_t n);
              Append at most n bytes from the string src to the string dest, returning a pointer to dest.

       int strcmp(const char *s1, const char *s2);
              Compare the strings s1 with s2.

       int strncmp(const char *s1, const char *s2, size_t n);
              Compare at most n bytes of the strings s1 and s2.

       char *strcpy(char *dest, const char *src);
              Copy the string src to dest, returning a pointer to the start of dest.

       char *strncpy(char *dest, const char *src, size_t n);
              Copy at most n bytes from string src to dest, returning a pointer to the start of dest.

我们如何想使用的话,需要先include一下头文件:

本次使用的代码框架如下:

#include <stdio.h>
#include <string.h>

int main(void)
{
        return 0;
}

1、strlen函数

从函数的名字上也不难看出,这个是跟字符串和长度有关系的函数。

如果第一次使用的话,可以使用:man strlen来查看这个函数的使用说明。

在这里插入图片描述

解释的非常详细。

可以看到strlen()函数在计算传入的字符串s的时候是不计算结束符"\0"的。

返回值是传入字符串s的字节数/字符格式。

#include <stdio.h>
#include <string.h>

int main(void)
{
        char str[12] = "I Love You!";
        char *pStr = "I Love You!";


        printf("str=%s\n",str);
        printf("pStr=%s\n",pStr);

        int strLen = strlen(str);
        int pStrLen = strlen(pStr);

        printf("str len:%d \n",strLen);
        printf("pStr len:%d \n",pStrLen);

        return 0;
}

结果:

可以看到无论是字符数组还是字符指针,都是可以统计出来有多少个字符的

zhenghui@zhlinux:~/桌面/code/string$ 
zhenghui@zhlinux:~/桌面/code/string$ make strtest && ./strtest 
cc     strtest.c   -o strtest
str=I Love You!
pStr=I Love You!
str len:11 
pStr len:11 
zhenghui@zhlinux:~/桌面/code/string$ 

计算时到底有没有跟数组的大小有关系?

	char str[12] = "I Love You!";
	char str2[100] = "I Love You!";
	char str3[100] = "I        Love      You!   ";
	
	int strLen = strlen(str);
	int strLen2 = strlen(str2);
	int strLen3 = strlen(str3);



	printf("str len:%d \n",strLen);
	printf("str2 len:%d \n",strLen2);
	printf("str3 len:%d \n",strLen3);

打印结果:

str len:11 
str2 len:11 
str3 len:26 

可以看到str2和str统计的数量是一样的。

从上面结果来看,数组的大小并不决定这个字符串的长度。

strlen函数只统计“\0”结尾之前的字数,而且不算“\0”这个字符。

2、strcat 和 strncat函数

不了解strcat函数可以直接在linux的命令行中输入:man strcat

就可以看到有两个相关的函数:

SYNOPSIS
       #include <string.h>

       char *strcat(char *dest, const char *src);

       char *strncat(char *dest, const char *src, size_t n);

还有很详细的说文。

The  strcat()  function  appends  the src string to the dest string, overwriting the terminating null byte
       ('\0') at the end of dest, and then adds a terminating null byte.  The strings may not  overlap,  and  the
       dest  string  must have enough space for the result.  If dest is not large enough, program behavior is un‐
       predictable; buffer overruns are a favorite avenue for attacking secure programs.

这个strcat函数是用来拼接字符串的,分别传入dest和src字符串,最终把src拼接到dest中进行返回。

实验代码:

zhenghui@zhlinux:~/桌面/code/string$ 
zhenghui@zhlinux:~/桌面/code/string$ cat strcatTest.c 
#include <stdio.h>
#include <string.h>

int main(void)
{
	char str1[12] = " I ";
	char str2[100] = " Love ";
	char *pStr = " You!iiiiii ";


	int sl = strlen(str1);
	printf("str1 len :%d \n",sl);

	printf("str1=%s\n",str1);
	printf("str2=%s\n",str2);
	printf("pStr=%s\n",pStr);

	strcat(str1,str2);
	strcat(str1,pStr);

	printf("#####################\n");
	printf("str1 :%s \n",str1);
	sl = strlen(str1);
	printf("str1 len :%d \n",sl);

	return 0;
}
zhenghui@zhlinux:~/桌面/code/string$

执行结果:

用法很简单,就是传入两个需要拼接的字符串即可

zhenghui@zhlinux:~/桌面/code/string$ make strcatTest && ./strcatTest
cc     strcatTest.c   -o strcatTest
str1 len :3 
str1= I 
str2= Love 
pStr= You!iiiiii 
#####################
str1 : I  Love  You!iiiiii  
str1 len :21 
zhenghui@zhlinux:~/桌面/code/string$ 

相比较来说,strncat比strcat安全一些。

例如:

如果a的空间是有限的,b的长度又很大。那么就会超出了a的大小。
那么为了安全,就可以使用strncat来指定拼接的大小。

strcat(a,b);

为了安全,我们可以使用strncat:

zhenghui@zhlinux:~/桌面/code/string$ 
zhenghui@zhlinux:~/桌面/code/string$ 
zhenghui@zhlinux:~/桌面/code/string$ cat strcatTest.c 
#include <stdio.h>
#include <string.h>

int main(void)
{
	char str1[12] = " I ";
	char str2[100] = " Love ";
	char *pStr = " You!iiiiii ";


	int sl = strlen(str1);
	printf("str1 len :%d \n",sl);

	printf("str1=%s\n",str1);
	printf("str2=%s\n",str2);
	printf("pStr=%s\n",pStr);

	//strcat(str1,str2);
	//strcat(str1,pStr);
	
	strncat(str1,str2,sizeof(str1) - strlen(str1) - 1);
	strncat(str1,pStr,sizeof(str1) - strlen(str1) - 1);

	printf("#####################\n");
	printf("str1 :%s \n",str1);
	sl = strlen(str1);
	printf("str1 len :%d \n",sl);

	return 0;
}
zhenghui@zhlinux:~/桌面/code/string$ 

可以看到结果也是正常的:

zhenghui@zhlinux:~/桌面/code/string$ make strcatTest && ./strcatTest
cc     strcatTest.c   -o strcatTest
str1 len :3 
str1= I 
str2= Love 
pStr= You!iiiiii 
#####################
str1 : I  Love  Y 
str1 len :11 
zhenghui@zhlinux:~/桌面/code/string$ 

我们使用sizeof(str1) - strlen(str1)就可以计算出str1所剩余的空间,-1是为了给“\0”留出空间。

strncat(str1,str2,sizeof(str1) - strlen(str1) - 1);

3、strcmp 和 strncmp函数

在C语言日常开发中,strcmp是非常常用的,我们做字符串比较,两个字符串是否相等,我们直接调用这个函数就可以很好的解决这个难题。

我们仍然可以使用:man strcmp来查看帮助手册:

SYNOPSIS
       #include <string.h>

       int strcmp(const char *s1, const char *s2);

       int strncmp(const char *s1, const char *s2, size_t n);

DESCRIPTION
       The strcmp() function compares the two strings s1 and s2.  The locale is not taken into account (for a lo‐
       cale-aware comparison, see strcoll(3)).  It returns an integer less than, equal to, or greater  than  zero
       if s1 is found, respectively, to be less than, to match, or be greater than s2.

       The strncmp() function is similar, except it compares only the first (at most) n bytes of s1 and s2.

RETURN VALUE
       The strcmp() and strncmp() functions return an integer less than, equal to, or greater than zero if s1 (or
       the first n bytes thereof) is found, respectively, to be less than, to match, or be greater than s2.

这是用来比较两个字符串的。

原型如下:

SYNOPSIS
       #include <string.h>

       int strcmp(const char *s1, const char *s2);

       int strncmp(const char *s1, const char *s2, size_t n);

我们需要传递两个字符串s1和s2;

返回值是:

返回值是一个大于、小于或等于0的值。
如果strcmp(s1,s2)==0:说明s1和s2相等;
如果strcmp(s1,s2) > 0:说明s1 > s2;
如果strcmp(s1,s2) < 0:说明s1 < s2;
当然了<=和>=运算符也是可以使用的。

RETURN VALUE
       The strcmp() and strncmp() functions return an integer less than, equal to, or greater than zero if s1 (or
       the first n bytes thereof) is found, respectively, to be less than, to match, or be greater than s2.

实验代码:

zhenghui@zhlinux:~/桌面/code/string$ cat strcmpTest.c 
#include <stdio.h>
#include <string.h>

int main(void)
{
	char str1[12] = "abc";
	char *str2 = "ABC";

	printf("str1=%s\n",str1);
	printf("str2=%s\n",str2);

	printf("#####################\n");
	
	int res1 = strcmp(str1,str2);
	printf("strcmp(str1,str2) :%d \n",res1);

	int res2 = strcmp(str2,str1);
	printf("strcmp(str2,str1) :%d \n",res2);

	if(res1 > 0)
	{
		printf("res1:%s > %s \n",str1,str2);
	}

	if(res2 < 0)
	{
		printf("res2:%s < %s \n",str2,str1);
	}


	return 0;
}
zhenghui@zhlinux:~/桌面/code/string$ 

实验结果:

zhenghui@zhlinux:~/桌面/code/string$ make strcmpTest && ./strcmpTest
make: “strcmpTest”已是最新。
str1=abc
str2=ABC
#####################
strcmp(str1,str2) :32 
strcmp(str2,str1) :-32 
res1:abc > ABC 
res2:ABC < abc 
zhenghui@zhlinux:~/桌面/code/string$ 

4、strcpy 和 strncpy函数

从字面上看,看着就很想copy拷贝。

没错,这个就是拷贝的功能。

同样,我们使用:man strcpy来查看帮助手册。

也有很详细的说明:

SYNOPSIS
       #include <string.h>

       char *strcpy(char *dest, const char *src);

       char *strncpy(char *dest, const char *src, size_t n);

DESCRIPTION
       The  strcpy() function copies the string pointed to by src, including the terminating null byte ('\0'), to
       the buffer pointed to by dest.  The strings may not overlap, and the destination string dest must be large
       enough to receive the copy.  Beware of buffer overruns!  (See BUGS.)

       The strncpy() function is similar, except that at most n bytes of src are copied.  Warning: If there is no
       null byte among the first n bytes of src, the string placed in dest will not be null-terminated.

       If the length of src is less than n, strncpy() writes additional null bytes to dest to ensure that a total
       of n bytes are written.

废话不多说,直接上代码:

zhenghui@zhlinux:~/桌面/code/string$ 
zhenghui@zhlinux:~/桌面/code/string$ cat strcpyTest.c 
#include <stdio.h>
#include <string.h>

int main(void)
{
	char str1[12] = " abc aowmdi9";
	char *str2 = " ABC 9999";

	printf("str1=%s\n",str1);
	printf("str2=%s\n",str2);

	printf("#####################\n");
	
	strcpy(str1,str2);


	printf("strcpy(str1,str2):%s \n",str1);


	return 0;
}
zhenghui@zhlinux:~/桌面/code/string$ 

实验结果:

zhenghui@zhlinux:~/桌面/code/string$ make strcpyTest && ./strcpyTest
make: “strcpyTest”已是最新。
str1= abc aowmdi9
str2= ABC 9999
#####################
strcpy(str1,str2): ABC 9999 
zhenghui@zhlinux:~/桌面/code/string$ 

通过下面代码可以看出,直接把str2的内容拷贝到了str1中,直接覆盖了。

strcpy(str1,str2);

重点:其实strcpy是用来解决我们不能用赋值运算符来赋值的操作的问题

那么什么时候,不能用“=”号来赋值呢?

例如:
我们定义一个数组,一开始不赋值,然后等我们业务逻辑到达的时候,再赋值:

char str3[10];

假设到了该赋值的地方:

str3 = "zhenghui";

这个地方会执行错误的。

可以看下执行结果:

zhenghui@zhlinux:~/桌面/code/string$ make strcpyTest && ./strcpyTest
cc     strcpyTest.c   -o strcpyTest
strcpyTest.c: In function ‘main’:
strcpyTest.c:11:7: error: assignment to expression with array type
   11 |  str3 = "zhenghui";//错误
      |       ^
make: *** [<内置>:strcpyTest] 错误 1
zhenghui@zhlinux:~/桌面/code/string$ 

像这种特殊的赋值,我们可以利用strcpy来解决:

strcpy(str3,"zhenghui");

执行就没问题了。

如果带参数n的话,就是用来限制copy的数据值的多少,也是为了安全才有的。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-03 10:58:44  更:2021-08-03 10:58:55 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/9 12:40:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码