C语言初阶——5.字符串

C语言初阶——5.字符串

1. 字符串操作

1.1 字符串遍历

可以通过数组方式遍历字符串。

char* str="Hello World";
for(int i = 0;'\0' != str[i];++i){
    printf("%c\n",str[i]);
}

也可以使用指针方式

char* str="Hello World";
for(int i = 0;'\0' != *str;++i){
    printf("%c\n",*(str+i));
}

指针方式可以简化成

char* str="Hello World";
for(;'\0' != *str;++str){
    printf("%c\n",*str);
}

甚至是

while('\0' != *str){
    printf("%c\n",*str++);
}
1.2 字符串赋值
char* s = "Hello World";
char* t;
t = s;
printf("%s\n",t);

没有产生新的字符串,只是s和t指向相同的字符串。下面是查看两个字符串的地址。

printf("%p\n",s);
printf("%p\n",t);
1.3 字符串输入输出
char str[8];
scanf("%s",str);
printf("%s\n",str);

scanf()读入一个单词直到空白符(空格、回车、Tab)
scanf()不安全,因为不知道要读入的内容长度,容易溢出。
例如:输入123456789
解决方式:指定读取的长度。

char str[8];
scanf("%7s",str);
printf("%s\n",str);

%s之间的数字表示最多允许输入的字符数,这个数字要比数组长度少1。

2. 字符串与函数

2.1 字符串传参

字符串传参方式与数组传参方式一样,只不过很多时候不需要传递字符串的长度(为什么?)。

void print_string(char str[]){
    printf(str);
}

或者

void print_string(char* str){
    printf(str);
}
2.2 字符串返回

字符串返回只能使用指针char*

3. 字符串指针与字符数组的区别

3.1 sizeof与strlen()
#include <stdio.h>
#include <string.h>

int main(){
    char arr[] = "Hello World";
    char* ptr = "Hello World";
    printf("sizeof(arr) = %ld\n",sizeof(arr));
    printf("strlen(arr) = %ld\n",strlen(arr));
    printf("sizeof(ptr) = %ld\n",sizeof(ptr));
    printf("strlen(ptr) = %ld\n",strlen(ptr));
}
3.2 替换字符

试一下下面三个例子

  1. 修改字符数组
#include <stdio.h>
#include <string.h>

int main(){
    char arr[] = "Hello World";
    arr[0] = 'h';
    arr[6] = 'w';
    printf("%s\n",arr);    
}
  1. 字符串指针
#include <stdio.h>
#include <string.h>

int main(){
    char* ptr = "Hello World";;
    *ptr = 'h';
    *(ptr+6) = 'w';
    printf("%s\n",ptr);    
}
  1. 指向字符数组的字符串指针
#include <stdio.h>
#include <string.h>

int main(){
    char arr[] = "Hello World";
    char* ptr = arr;
    *ptr = 'h';
    *(ptr+6) = 'w';
    printf("%s\n",ptr);    
}
  1. const字符数组
#include <stdio.h>
#include <string.h>

int main(){
    const char arr[] = "Hello World";
    arr[0] = 'h';
    arr[6] = 'w';
    printf("%s\n",arr);    
}
  1. 指向const字符数组的字符串指针
#include <stdio.h>
#include <string.h>

int main(){
    const char arr[] = "Hello World";
    char* ptr = arr;
    *ptr = 'h';
    *(ptr+6) = 'w';
    printf("%s\n",ptr);    
}

决定能否修改的是指针指向的值能否修改。const的限制只针对定义为const的变量。

3.3 字符串字面量初始化

字符串字面量初始化字符数组
字符串字面量初始化字符串指针

char* str1 = "Hello World";
char str2[] = "Hello World";

str1[5] = '\0'; // Error
str2[5] = '\0'; // OK

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

str1是一个指针,初始化指向一个字符串常量。(在C99标准中,str1报警告,提示应该使用const char*)
修改字符串常量可能会导致严重后果。
str2是一个字符数组,初始化把字符串字面量自动复制到数组中。

如何选择?

  1. 如果需要构造字符串使用数组;如果需要处理字符串使用指针。
  2. 字符串不需要修改使用字符串字面量初始化字符串指针。
  3. 字符串需要修改使用字符串字面量初始化字符数组。

4. 字符串函数

4.1 字符串长度
size_t strlen(const char *s);

返回字符串长度不包含\0

4.2 字符串比较
int strcmp(const char *s1,const char *s2);

比较两个字符串
返回0,表示s1 == s2
返回>0,表示s1 > s2
返回<0,表示s1 < s2
为什么字符串不能直接比较?
为什么字符串比较会有大小?

4.3 字符串拷贝
char* strcpy(char* restrict dst,const char* restrict src);

把字符换src拷贝到dst。
restrict是C99关键字,表示src和dst不能重叠,便于并行处理。
返回值为dst,便于连接。
连续赋值。

复制一个字符串

// char* dst = (char*)malloc(strlen(src)+1);
char dst[strlen(src)+1];
strcpy(dst,src);
4.4 字符串连接
char* strcat(char* restrict s1,const char*restrict s2);

把s2拷贝到s1的后面,拼接成一个长的字符串。
返回s1,注意:s1必须有足够的空间。

char* a="Hello";
char* b="World";
char res[strlen(a)+strlen(b)+1] = {0};
strcat(strcat(res,a),b);

strcpy和strcat都会有安全问题:dst空间不足,出现越界。

4.5 字符查找
char* strchr(const char*s,int c);
char* strrchr(const char*s,int c);

返回找到字符的指针,没找到返回NULL
如何查找第二个?

4.6 子串查找
char* strstr(const char*s1,const char*s2);
char* strcasestr(const char*s1,const char*s2);

5. 文档

stdio.h

  • sprintf:数据按格式写入字符串
  • sscanf:按格式从字符串读出数据

stdlib.h

  • atof:字符串转浮点数
  • atoi:字符串转整数
  • atol:字符串转长整数

string.h
复制

连接

比较

查找

  • strchr:查找字符串中第一个出现指定字符的位置
  • strrchr:查找字符串中最后一个出现指定字符的位置
  • strstr:查找字符串中第一个出现指定子串的位置
  • strtok:切分字符串

其他

发布了68 篇原创文章 · 获赞 16 · 访问量 8456

猜你喜欢

转载自blog.csdn.net/weixin_41969690/article/details/103733928
今日推荐