一.字符串
1.概念
计算机使用多个连续的字符类型的存储位置来记录文字信息
C语言中使用第一个字符的地址来代表整段文字信息
使用ASCII表中值为0的字符 (’\0’) 表示文字信息的结束位置
所有有效字符和最后的’\0’合起来叫做字符串
2.字符串的使用
(1)字符串常量(字符串字面值)
在C语言中用双引号("")引来来的内容叫做字符串常量(“abc” “123”)
字符串常量被保存在代码段,该段的内容在程序运行期间不能修改
编译器遇到字符串常量自动用第一个字符的地址来代替字符串常量(不能使用 sizeof求字符串的大小)
相同内容的字符串常量在内存中只保存一份
需要使用字符指针记录字符串常量时,将字符指针声明成常量指针(const char *),避免去修改导致段错误
(2)字符数组
可以使用字符数组来在程序中表示字符串
编译器不会自动往字符数组后加结束符(‘\0’),需要手动添加’\0’
char str_arr[] = {'a','b','c','\0'}
char str_arr[] = {'a','b','c',0}
可以使用字符串常量来初始化字符数组,此时结束符会被自动添加
char str_arr[] = "1234";
使用字符串常量来初始化字符数组只是将常量中的内容赋值到数组空间中来,完成初始化以后他们相互独立,互相不影响
字符数组存放的段落和其位置有关,但是一定可以修改
3.字符串的输入输出
printf打印字符串对应的占位符是 %s
scanf函数可以从键盘获取字符串,但是这种方式不安全,不可靠
scanf函数输入字符串是不限定长度,容易造成内存越界
可以使用fgets函数来获取键盘输入的字符串,用法如下:
fgets(字符数组首地址,字符数组长度,stdin);
注:最多从键盘读取字符长度-1个数的字符
fgets函数默认在最后的字符后面加上换行符("\n")
多次输出字符串可能导致缓冲区存在垃圾数据,所以我们在多次字符串的输入之间要清除缓冲区
scanf("%*[^\n]");
scanf("%*c");
或者
while(getchar()!='\n');
4.字符串相关标准函数
printf() scanf() fgets() getchar() rand() srand() time()
C语言提供了一系列的标准函数来处理字符串,使用这些函数需要包含头文件 string.h
(1)strlen
语法:
#include <string.h>
size_t strlen(const char *s)
该函数用来计算字符串中有效字符个数(字符串长度),不包括’\0’
传入要计算的字符串,返回有效字符个数(size_t其实就是无符号整型)
例:
#include <stdio.h>
#include <string.h>
int main()
{
char name[20] = {};
printf("len = %d\n", strlen("hello"));
printf("请输入名字:");
fgets(name,20,stdin);
printf("name = %s,len = %d\n", name, strlen(name));
}
(2)strcpy
语法:
#include <string.h>
char *strcpy(char *dest,const char *src);
char *strncpy(char *dest,const char *src,size_t n);
strcpy函数是将一个给定的字符串中的所有字符拷贝到一个字符数组中
src -----> dest
strncpy函数将一个给定的字符串中的前n个字符拷贝到一个字符数组中(最多n个)
src(前n个字符)----->dest
例:
#include <string.h>
int main()
{
char name[20] = {};
char buf[20] = {};
printf("请输入名字:");
fgets(name,20,stdin);
strcpy(buf,"byebye!");
printf("buf = %s\n", buf);
strcpy(buf,name);
strncpy(buf,name,3);
printf("buf = %s\n", buf);
return 0;
}
(3)strcat
语法:
#include <string.h>
char *strcat(char *dest, const char *src);
char *strncat(char *dest, const char *src, size_t n);
strcat实现的是字符串的拼接功能,将一个字符串拼接到前一个的末尾
strncat实现的是字符串的拼接功能,将一个字符串的前n个字符拼接到前一个的末尾(最多n个)
例:
#include <stdio.h>
#include <string.h>
int main()
{
char name[20] = {};
char buf[20] = {};
printf("请输入名字:");
fgets(name,20,stdin);
strcpy(buf,"byebye!");
printf("buf = %s\n", buf);
strcat(buf,name);
printf("buf = %s\n", buf);
strncat(buf,name,3);
printf("buf = %s\n", buf);
return 0;
}
(4)strcmp
语法:
#include <string.h>
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
strcmp函数实现的是两个字符串内容的比较,如果两个字符串内容相同,返回0,如果前一个大于后一个返回大于0,如果前一个小于后一个返回小于0
比较方法是从前往后比较,比较第一个不同的字符的ASCII码大小,前面字符串的ASCII码大,返回1,否则返回-1
大多数情况下我们只比较两个字符串是否相同
strncmp函数用来比较两个字符串的前n个字符是否相同
例:
#include <stdio.h>
#include <string.h>
int main()
{
char name[20] = {};
printf("请输入名字:");
fgets(name,20,stdin);
printf("%d\n", strcmp(name,"abc"));
printf("%d\n", strncmp(name,"abc",2));
return 0;
}
5.记录多个字符串
使用字符类型的二维数组可以表示多个相关的字符串
由于二维数组每组的长度一样,保存多个字符串需要将二维数组每组的长度设置为超多最长字符串的长度,这样容易造成空间浪费
通常我们会使用字符类型的指针数组来表示多个字符串,这种类型的表示方法中字符串的空间不是由数组提供的。
语法:
char *数组名[元素个数];
例:
#include <stdio.h>
#include <string.h>
int main()
{
char *str1[7] = {"hello","Are you OK","bye",
"today is sunning","How are you","How old are you",NULL};
int i = 0;
/*
for(i=0;i<6;i++){
printf("%s\n",str1[i]);
}*/
char **pp = NULL;
for(pp=str1;*pp;pp++){
printf("%s\n",*pp);
}
return 0;
}