13.1 字符串字面量
#include <stdio.h>
int main()
{
printf("this is String")
}
13.1.3 如何存储字符串字面量
如存储 “abc” 实际上就是存储
空字符串的存储
note
- 这里有一个需要了解的是,当我 printf 一个 “abc” 时,我传递的实际上是一个指针,而且是 a 的地址
#include <stdio.h>
int main()
{
char *p;
p = "abc";
printf("%c",p[2]);
}
// 输出
c
13.2 字符串变量
假设需要变量存储 80 个字符,则需要申请 81 个字符的数组,最后一个用作空字符。
int main()
{
char date1[8] = "June 14";
// 等价于 char date1[8] = {'J','u','n','e',' ','1','4'};
}
如果声明的字符数组比实际存储字符长,在内存中会是什么样呢
char date1[9] = "June 14";
注意,不能声明一个长度小于(字符数量+空字符)
你也可以不指定长度,但编译器在编译时会自动确定。
#include <stdio.h>
int main()
{
char date[] = "June 14";
printf("%d",sizeof(date));
}
// 输出
8
13.2.2 字符数组与字符指针
注意,二者并不是等价的
#include <stdio.h>
int main()
{
char date[] = "June 14";
char *date1 = "June 14";
}
字符数组可以操纵每一个字符元素,但字符指针不行,它的整个被当作一个整体来看待。
#include <stdio.h>
int main()
{
char date[] = "June 14";
char *date1 = "June 14";
date[0] = 'h';
printf("%c",date[0]);
}
// 输出,这样的操作只能在字符数组中出现
h
13.3 字符串的读/写
13.3.1 使用 printf 或者 puts 来写字符串
printf 函数逐个写字符,遇到空字符才停止,如果空字符丢失,则会一直写,直到在内存中遇见空字符。
#include <stdio.h>
int main()
{
char str[] = "Are we having fun yet?";
printf("%s",str);
}
// 输出
Are we having fun yet?
你可以通过 %.ms 来设置输出的字符串数量
#include <stdio.h>
int main()
{
char str[] = "Are we having fun yet?";
printf("%.6s",str);
}
// 输出
Are we
你也可以用 puts 来输出
#include <stdio.h>
int main()
{
char str[] = "Are we having fun yet?";
puts(str);
}
// 输出
Are we having fun yet?
13.3.2 使用 scanf 函数和 gets 函数读字符串
1. scanf 的使用
- 不需要在 str 前面添加 &,因为 str 是数组名,编译器自动把它当作指针处理
- scanf 会跳过开头的空格,且在遇到下一个空格的时候停止
- gets 不会跳过空格,而是原样输出,直到遇到换行符才停止
#include <stdio.h>
int main()
{
char str[10];
printf("在这里开始输入:");
scanf("%s",str);
printf("输出刚才的内容:%s",str);
}
// 输出
在这里开始输入:To c, or not to c: that is the question
输出刚才的内容:To
#include <stdio.h>
int main()
{
char str[10];
printf("在这里开始输入:");
gets(str);
printf("输出刚才的内容:%s",str);
}
// 输出
在这里开始输入:To c, or not to c: that is the question
输出刚才的内容:To c, or not to c: that is the question
13.3.3 逐个字符读字符串
scanf 和 gets 都有风险,自己编写一个函数读取字符
#include <stdio.h>
int read_line(char str[],int n);
int main()
{
char str[10];
read_line(str,10);
printf("%s",str);
}
int read_line(char str[],int n)
{
char ch;
int i=0;
printf("在这里开始:");
while((ch = getchar())!='\n')
if(i<n)
str[i++] = ch;
str[i] = '\0';
return i;
}
// 输出
在这里开始: abc_12,3
abc_12,3
13.4 访问字符串中的字符
#include <stdio.h>
int main()
{
char *s = "Are you OK?";
int count = 0;
for(;*s!='\0';s++)
{
if(*s ==' ')
count++;
}
printf("%d\n",count);
}
// 输出
2
13.5 字符串内置函数
13.5.1 strcpy
char strcpy(char s1,char *s2)
将字符串 s2 的值赋给 s1,并返回 s1。记住,这里必须是将 s 声明为数组的形式,不能是指针的形式
#include <stdio.h>
#include <string.h>
int main()
{
// 这样就是错误的
// char *s1;
// char *s2 = "this is s2";
char s1[100];
char s2[] = "this is s2";
strcpy(s1,s2);
printf("%s\n",s1);
}
// 输出
this is s2
13.5.2 strcat
追加 s2 到 s1 的后面
#include <stdio.h>
#include <string.h>
int main()
{
char s1[] = "this is s1";
char s2[] = "this is s2";
strcat(s1,s2);
printf("%s\n",s1);
}
// 输出
this is s1this is s2
13.5.3 strcmp
比较两个字符串的大小。
比较原则:
- 长度相同,看某个字符的 ascll 码值
- 长度不同,长度短的小
- 如果长度不同,存在字符不同,优先比较字符
- 小于返回 -1,等于返回 0,大于返回 1
#include <stdio.h>
#include <string.h>
int main()
{
char s1[] = "this is s1";
char s2[] = "this is s2";
printf("%d\n",strcmp(s1,s2));
}
// 输出
-1
#include <stdio.h>
#include <string.h>
int main()
{
char s1[] = "this is";
char s2[] = "this is s2";
printf("%d\n",strcmp(s1,s2));
}
// 输出
-1
#include <stdio.h>
#include <string.h>
int main()
{
char s1[] = "this iz";
char s2[] = "this is s2";
printf("%d\n",strcmp(s1,s2));
}
// 输出
1
13.5.4 strlen
计算字符串长度
#include <stdio.h>
#include <string.h>
int main()
{
char s1[] = "this iz";
char s2[] = "this is s2";
printf("%d\n",strcmp(s1,s2));
}
// 输出
7
13.7 字符串数组
如何存储字符串数组?
一个简单的浪费的方式是建立二维数组
char str[][8] = {"Mercury","Venus","Earth",
"Mars","Jupi ter","Saturn",
"Uranus","Neptune","pluto"};
图示就是这样,可以看出很浪费空间,毕竟不是每个字符都占用了所有格子
另一种更好的方式就是建立指向字符串的指针数组
char *str[] = {"Mercury","Venus","Earth",
"Mars","Jupi ter","Saturn",
"Uranus","Neptune","pluto"};
其图示如下: