??strlen即为string length,顾名思义该函数是用来求字符串长度的。在介绍strlen函数之前,我们要先介绍一下"\0"这个转义字符。任何一个字符串后面都会隐藏一个"\0",该转义字符是字符串结束的标志,所以我们在使用strlen函数求字符串长度时,遇到"\0"时停止读取,此时"\0"前的字符个数就是字符串的长度。
注意:
??这里的"\0"只是结束标志,并不算一个字符!
示例1:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
printf("%d\n", strlen("xxccyy"));
system("pause");
return 0;
}
我们将字符串"xxccyy"在内存的存储结构展示如下:
示例2:
??在c语言中,字符串并没有作为一种独立的数据类型进行定义。相反,字符串被表示为字符数组或字符指针。以下是两种常见的表示字符串的方法:
char str[20] = "Hello, World!"; // 声明一个字符数组来存储字符串
char *str = "Hello, World!"; // 声明一个指向字符的指针,指向字符串常量
??接下来我们介绍使用字符数组存储字符串的每一个字符,使用这种定义方式对于strlen的求解有何不同呢?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char arr1[] = {'x','x','c','c','y','y'};
char arr2[] = {'x','x','c','c','y','y','\0'};
printf("%d\n", strlen(arr1));
printf("%d\n", strlen(arr2));
system("pause");
return 0;
}
??arr1数组只是单纯把字符串“abcdef”的每一个字符用数组存储起来,而arr2数组则是多存储了一个“\0",可以看到arr1数组的长度为9,arr2数组的长度为6,接下来我们将展示两个数组在内存中的存储状态。
?? arr2数组的存储情况和示例1字符串的存储情况相同,而arr1却不同。对于arr2我们不进行说明,接下来我们分析下为什么arr1数组的长度为9。
??上文我们说过字符串结束标志为"\0",但是我们的arr1数组没有额外存储"\0",所以编译器在读取时,并不会像我们所期望的那样停止读取,故长度当然不会为6。但是为什么最终读取的长度为9,是因为在读取时,编译器读取完arr1时会继续往后读取,直到读取到”\0",arr1在读取完第9个字符后才会遇到”\0";由于每个人的电脑和编译器不同,读取的长度也不一样,所以arr1这种情况一般我们认为它读取的结果为随机值!
示例3:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
printf("%d\n", strlen("xcy\0zfr"));
system("pause");
return 0;
}
示例3是为了进一步说明字符串结束标志"\0"的重要性。
??sizeof是计算变量在内存的占空间的大小,单位是字节。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
printf("sizeof(char): %d\n", sizeof(char));
printf("sizeof(short): %d\n", sizeof(short));
printf("sizeof(int): %d\n", sizeof(int));
printf("sizeof(long): %d\n", sizeof(long));
printf("sizeof(long long): %d\n", sizeof(long long));
printf("sizeof(float): %d\n", sizeof(float));
printf("sizeof(double): %d\n", sizeof(double));
system("pause");
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char c = 'a';
int i = 1;
short s = 1;
long l = 1;
long long ll = 1;
float f = 1.0;
double d = 1.0;
printf("sizeof(c): %d\n", sizeof(c));
printf("sizeof(s): %d\n", sizeof(s));
printf("sizeof(i): %d\n", sizeof(i));
printf("sizeof(l): %d\n", sizeof(l));
printf("sizeof(ll): %d\n", sizeof(ll));
printf("sizeof(f): %d\n", sizeof(f));
printf("sizeof(d): %d\n", sizeof(d));
system("pause");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("sizeof(char*): %d\n", sizeof(char*));
printf("sizeof(short*): %d\n", sizeof(short*));
printf("sizeof(int*): %d\n", sizeof(int*));
printf("sizeof(long*): %d\n", sizeof(long*));
printf("sizeof(long long*): %d\n", sizeof(long long*));
printf("sizeof(float*): %d\n", sizeof(float*));
printf("sizeof(double*): %d\n", sizeof(double*));
system("pause");
return 0;
}
如想得到数组的元素个数,有以下两种方法:
1.总长度/相对应的数据类型长度
2.总长度/首元素长度
#include <stdio.h>
#include <stdlib.h>
int a[]={1,2,3,4,5};
short b[]={1,2,3,4,5};
long c[]={1,2,3,4,5};
float d[]={1,2,3,4,5};
double e[]={1,2,3,4,5};
char f[]="12345";
int main(void)
{
printf("a=%d,b=%d,c=%d,d=%d,e=%d,f=%d\n",
sizeof(a)/sizeof(int), sizeof(b)/sizeof(short), sizeof(c)/sizeof(long),sizeof(d)/sizeof(float),sizeof(e)/sizeof(double),sizeof(f)/sizeof(char));
printf("a=%d,b=%d,c=%d,d=%d,e=%d,f=%d\n",
sizeof(a)/sizeof(a[0]), sizeof(b)/sizeof(b[0]), sizeof(c)/sizeof(c[0]),sizeof(d)/sizeof(d[0]),sizeof(e)/sizeof(e[0]),sizeof(f)/sizeof(f[0]));
system("pause");
return 0;
}
sscanf函数是C语言中的一个标准库函数,用于从格式化的字符串中读取输入。
sscanf的函数原型:
#include <stdio.h>
int sscanf(const char *str, const char *format, ...);
其中,str表示要读取的字符串,format表示格式控制字符串,…表示可变参数列表。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int year, month, day;
int converted = sscanf("20231215", "%04d%02d%02d", &year, &month, &day);
printf("converted=%d, year=%d, month=%d, day=%d\n", converted, year, month, day);
system("pause");
return 0;
}
??“%04d%02d%02d"是用来解析字符串的格式,%表示格式转换的开始,d表示转换为一个整数,04作为d的修饰,表示这是一个长度为4位的整数,不足4位时以0补齐。
??返回值converted等于3,表示有3个数据成功转换,转换成功数目同时取决于被解析的字符串以及其转换格式,如果我们把例子中的格式改为”%04d%02d",那么sscanf将只返回2,day的数值不会被sscanf更改。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
double longitude, latitude;
int converted = sscanf("113.123456789,31.123456789", "%lf,%lf", &longitude, &latitude);
printf("converted=%d, longitude=%.9lf, latitude=%lf\n", converted, longitude, latitude);
system("pause");
return 0;
}
sscanf的格式字符串中,f表示这是一个浮点数,其修饰词l表示这是一个double的浮点数。
取到指定字符为止:运算符 %[ ]
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char str[100];
sscanf("Lucky xu123", "%[^ ]", str); //取遇到空格为止字符串
printf("str=%s\n", str);
system("pause");
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char str[100];
sscanf("Lucky xu123", "%[^1]", str); //取遇到空格为止字符串
printf("str=%s\n", str);
system("pause");
return 0;
}
??我们设定运算符为% [^1] ,即遇到1截止,最终结果也符合预期。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char str[100];
sscanf("654321abcdedfABCDEF", "%[1-9a-z]", str); //只取数字和小写字符
printf("str=%s\n", str);
system("pause");
return 0;
}
[a-z]表示读取a-z的所有字符,[^a-z]表示读取除a-z以外的所有字符 。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char str[100];
sscanf("BCDEF123456abcdedf", "%[^a-z]", str); //取遇到小写字母为止的字符串
printf("str=%s\n", str);
system("pause");
return 0;
}
??在使用STM32驱动TFT屏幕时,发现厂家给的驱动函数只支持16位无符号整形数据,即可显示的范围为0~65535,那么我们想显示65535以外的数则需要自己写驱动函数,本着偷懒的原则我发现了厂家提供了字符串驱动函数,那么我们只需要将65535以外的数转为字符串进行显示即可。
这便需要使用我们的sprintf函数,sprintf的函数原型:
#include <stdio.h>
int sprintf( char *buffer, const char *format, [ argument] … );
参数列表:
buffer:char型指针,指向欲写入的字符串地址。
format:char型指针,指向的内存里面存放了格式字符串。
[argument]…:可选参数,可以是任何类型的数据。
返回值:字符串长度(strlen)
#define _USE_MATH_DEFINES 1 //如果要使用<math.h>里面的宏,需要定义_USE_MATH_DEFINES
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int main()
{
char str[80];
sprintf(str, "Pi 的值 = %f", M_PI);
puts(str);
system("pause");
return(0);
}
#include <stdio.h>
#include <stdlib.h>
int main()
{
char dest[20];
sprintf(dest, "Hello World!");
puts(dest);
system("pause");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num = 886;
char str[] = "byebye";
char dest[20];
sprintf(dest, "%s is %d", str, num);
puts(dest);
system("pause");
return 0;
}
sprintf函数的返回值不包含目标字符串末尾自动添加的’\0’
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num = 886;
char str[] = "byebye";
char dest[20];
int len = sprintf(dest, "%s is %d", str, num);
puts(dest);
printf("len = %d\n", len);
system("pause");
return 0;
}
当你想要在一个字符数组的某个位置开始时,那么第一个参数就要传对应位置的地址。
#include <stdio.h>
#include <stdlib.h>
int main()
{
char dest[40] = "I love ";
char str[] = "this world!";
sprintf(dest + 7, str);
puts(dest);
system("pause");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main()
{
char a[100] = { 0 };
sprintf(a, "你好,我是%s博主", "Jack.xu");
printf("%s\n", a);
system("pause");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main()
{
char dest[100];
char str1[] = "Hello";
char str2[] = "World!";
int len1 = sprintf(dest, "%s, % s", str1, str2);
printf("%s\n%d\n", dest, len1);
system("pause");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main()
{
unsigned int number = 655350;
char buffer[10];
sprintf(buffer, "%d", number);
printf("%s\n",buffer);
system("pause");
return 0;
}
??在这里我们将655350转化为字符串。可以看出,利用sprinrf函数可以解决我们背景中的问题。
?? strcpy函数是将一个字符串复制到另一块空间地址中的函数,‘\0’是停止拷贝的终止条件,同时也会将 ‘\0’ 也复制到目标空间。
??strcpy的函数原型:
#include <string.h>
char *strcpy(char *dest, const char *src);
函数的参数:
函数的返回值类型:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char arr[10] = { 0 };
const char* p = "abcdef";
strcpy(arr, p);
printf("%s\n", arr);
system("pause");
return 0;
}