第9周:字符串
C
9.1.1 字符串:字符串
字符数组
- char word[] = {'H','E','L','L','O','!'};
- 这不是C语言的字符串,因为不能用字符串的方式做计算
字符串
char word[] = {'H','E','L','L','O','!','\0'};
以0(整数0结尾的一串字符)
- 0(int, 4字节)或‘\0’(1字节)是一样的,但是和‘0’(ASCII码,48)不同
- 0标志字符串的结束,但它不是字符串的一部分
- 字符串以数组的形式存在,以数组或指针的形式访问
- string.h 里有很多处理字符串的函数
字符串变量
- char *str = "Hello";
- char word[] = "Hello";
- char line[10] = "Hello";
字符串常量
- “Hello”
- “Hello”会被编译器变成一个字符数组放在某处,这个数组的长度是6,结尾还有表示结束的0
- 两个相邻的字符串常量会被自动连接起来
字符串总结
- C语言的字符串是以字符数组的形态存在的
- 不能用运算符对字符串做计算
- 通过数组的方式可以遍历字符串
- 唯一特殊的地方是字符串字面量可以用来初始化字符数组
- 以及C的标准库提供了一系列字符串函数
9.1.2 字符串:字符串变量
字符串常量
char * s = "Hello,world!";
- s是一个指针,初始化为指向一个字符串常量
- 由于这个常量所在的地方,所以实际上s是const char* s,但是由于历史的原因,编译器不接受不带const的写法
- 但是试图对s所指的字符串做写入会导致严重的后果
- 如果需要修改字符串,应该用数组:
char s[] = "Hello, world!";
指针还是数组?
- char *str = "Hello";
- char word[] = "Hello";
- 数组:这个字符串在这里
指针:这个字符串不知道在哪里(只读不写)
如果要构造一个字符串-->数组
- 如果要处理一个字符串-->指针
char* 是字符串?
- 字符串可以表达为char*的形式
- char*不一定是字符串
- 本意是指向字符的指针,可能指向的是字符的数组(就像int*一样)
- 只有它所指的字符数组有结尾的0,才能说它所指的是字符串
9.1.3 字符串:字符串的输入输出
字符串赋值?
- char *t = "title";
- char *s
- s = t
- 并没有产生新的字符串,只是让指针s指向了t所指的字符串,对s的任何操作就是对t做的
字符串输入输出
安全输入
- char string[8];
- scanf("%7s", string);
- 在%和s之间的数字表示最多允许读入的字符的数量,这个数字应该比数组的大小小一
常见错误
- char *string
- scanf("%s", string);
- 以为char*是字符串类型,定义了一个字符串类型的变量string就可以直接用了
- 由于没有对string初始化为0,所以不一定每次运行都出错
空字符串
- char buffer[100]="";
- 这是一个空的字符串,buffer[0] == '\0'
- char buffer[] = ""
9.1.4 字符串:字符串数组,以及程序参数
字符串数组
- char **a
- a是一个指针,指向另一个指针,那个指针指向一个字符(串)
- char a[][]
程序参数
- int main(int argc, char const *argv[])
- argv[0] 是命令本身
9.2.1 字符串函数:单字符输入输出
putchar
- int putchar(int c);
- 向标准输出写一个字符
- 返回写了几个字符,EOF(-1)表示写失败
9.2.2 字符串函数:字符串函数strlen
string.h
- strlen
- strcmp
- strcpy
- strcat
- strstr
strlen
- size_t strlen(const char *s);
- 返回s的字符串长度(不包括结尾的0)
#include <stdio.h>
#include <string.h>
size_t mylen(const char *s)
{
int idx = 0;
while(s[idx] != '\0') {
idx++;
}
return idx;
}
int main(int argc, char const *argv[])
{
char line[] = "Hello";
printf("strlen=%lu\n", mylen(line));
printf("sizeof=%lu\n", sizeof(line));
return 0;
}
strlen=5
sizeof=6
9.2.3 字符串函数:字符串函数strcmp
strcmp
- int strcmp(const char *s1, const char *s2);
- 比较两个字符串,返回:
- 0:s1 == s2
- 1:s1 > s2
- -1:s1 < s2
#include <stdio.h>
#include <string.h>
int mycmp(const char *s1, const char *s2)
{
// int idx = 0;
// while(s1[idx]==s2[idx] && s1[idx] !='\0'){
//// if(s1[idx] != s2[idx]){
//// break;
//// } else if(s1[idx]=='\0'){
//// break;
//// }
// idx++;
// }
while(*s1==*s2 && *s1 != '\0'){
s1++;
s2++;
}
// return s1[idx]-s2[idx];
return *s1 - *s2;
}
int main(int argc, char const *argv[])
{
char s1[] = "abc";
char s2[] = "abc ";
printf("%d\n", mycmp(s1,s2));
printf("%d\n", 'a'-'A');
return 0;
}
-32
32
9.2.4 字符串函数:字符串函数strcpy
strcpy
- char *strcpy(char *restrict dst, const char *restrict src)
- 把src的字符串拷贝到dst
- 返回dst
复制一个字符串
- char *dst = (char *)malloc(strlen(src)+1);
- strcpy(dst,src);
#include <stdio.h>
#include <string.h>
char* mycpy(char* dst, const char* src)
{
// int idx = 0;
// while (src[idx]){
// dst[idx] = src[idx];
// idx++;
// }
// dst[idx] = '\0';
char* ret = dst;
while(*dst++ = *src++)
;
*dst = '\0';
return ret;
// return dst;
}
int main(int argc, char const *argv[])
{
char s1[] = "abc";
char s2[] = "abc";
mycpy(s1,s2);
return 0;
}
9.2.5 字符串函数:字符串函数strcat
strcat
- char * strcat(char *restrict s1, const char *restrict s2);
- 把s2拷贝到s1的后面,接成一个长的字符串
- 返回s1
- s1必须具有足够的空间
安全问题
安全版本
- char * strncpy(char *restrict dst, const char *restrict src, size_t n);
- char * strncat(char *restrict s1, const char *restrict s2, size_t n);
- int strncmp(const char *s1, const char *s2, size_t n);
9.2.6 字符串函数:字符串搜索函数
在字符串中找字符
- char * strchr(const *s, int c);
- char * strrchr(const char *s, int c);
- 返回NULL表示没有找到
#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
char s[] = "hello";
char *p = strchr(s, 'l');
char c = *p;
*p = '\0';
// p = strchr(p+1, 'l');
char *t = (char*)malloc(strlen(s)+1);
strcpy(t,s);
printf("%s\n", t);
free(t);
return 0;
}
he
字符串中找字符串
- char * strstr(const char *s1, const char *s2);
- char * strcasestr(const char *s1, const char *s2);