C基础:04.字符串常见操作和指针练习

1.字符串定义

字符串以 \0 结尾,动态开辟内存的时候也需要多考虑一位

定义方式有两种:

  1. char str[] = {'E','a','s','t','r','i','s','e','\0'}; : 可以修改
  2. const char *str1 = "Eastrise";:不能修改,字符串常量存放再全局的const内存区
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int main(){
// 第一种 字符串数组
char str[] = {'E','a','s','t','r','i','s','e','\0'};

str[2] = 'y';

printf("%s\n",str); // 字符串结尾必须是 '\0',开辟内存也需要多开辟一个

// 第二种 不加 const 会警告:deprecated conversion from string constant to 'char*'
// 原因:
// "Eastrise"是字符串常量, 内存分配在全局的const内存区
// char * 声明了一个指针,而这个指针指向的是全局的const内存区,const内存区当然不会让你想改就改的。所以,如果你一定要写这块内存的话,那就是一个非常严重的内存错误。
const char *str1 = "Eastrise";

// str1[2] = 'y';

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

// 两种定义的区别:一个能修改,一个不能修改

}

2.字符串长度获取

  1. strlen(name)

  2. 通过sizeof 进行计算(不好使),不对

    1
    2
    3
    4
    const char str[] = {'E','a','s','t','r','i','s','e','\0','i','s'};

    // 怎么获取长度?有一种方式计算(不好使)
    printf("length is %d",sizeof(str)/sizeof(char)); // 打印出来 11,实际结果应该是 8
  3. 写一个方法读取字符串的长度

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int strlen_(char *str){
    // 怎么获取字符串的长度? 不断读取字符,判断末尾 '\0'

    int len = 0;
    while (*str != '\0')
    {
    len++;
    str++;
    }
    return len;
    }

3.字符串与基本数据类型的转换

  • atoi(num_str); // str 转 int如果不能转换就是 0 ,后面如果有其他不是数字的就会被剔除 12xxx -> 12
  • atof(num_str); // str 转 float // 如果不能转换返回的是默认值 0.000000
  • strtod(num_str, NULL); // str 转 double // 如果不能转换返回的是默认值 0.000000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main(){

const char* num1 = "1"; // -> int float double
const char* num_str1 = "12.0xxx";
int number1 = atoi(num_str1); // 如果不能转换就是 0 ,后面如果有其他不适数字的就会被剔除 12xxx -> 12
printf("number1 is %d\n",number1);

const char* num_str2 = "12.5f";
float number2 = atof(num_str2); // 如果不能转换返回的是默认值 0.0000
printf("number2 is %f\n",number2);

const char *num_str3 = "12.5xx";
double number3 = strtod(num_str3,NULL);// 如果不能转换就是 0.000 ,后面如果有其他不适数字的就会被剔除 12.5xxx -> 12.5000

printf("number3 is %lf\n",number3);
getchar();
}

打印结果:

1
2
3
number1 is 12
number2 is 12.500000
number3 is 12.500000

4.字符串的比较

  • int rc = strcmp(str1, str2); // 区分大小写比较,rc == 0代表相等,rc > 0 str1 比 str2 大
  • int rc = strcmpi(str1, str2); // 不区分大小写比较,rc == 0代表相等,反之不相等
  • int rc = strncmp(str1, str2,7); // 区分大小写比较, count 代表的是比较字符串前几个是否相等
  • int rc = strnicmp(str1, str2,7); // 不区分大小写比较, count 代表的是比较字符串前几个是否相等
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main(){
const char* str1 = "Eastrise";
const char* str2 = "eastrise";

// 大于小于等于
// int rc = strcmp(str1,str2); // 区分大小写比较
// int rc = _strcmpi(str1,str2); // 不区分大小写比较 c strcmpi c++ _strcmpi , android ndk strcasecmp;

// 比较前几个
// int rc = strncmp(str1,str2,7); // count 达标的是比较字符串前几个是否相等
int rc = _strnicmp(str1,str2,6); // 不区分大小写的比较
if(rc == 0) {
printf("相等");
}else{
printf("不相等");
}

getchar();
}

5.字符串查找,包含

  • char* pos = strstr(str, substr); // 返回的是字符串第一次出现的位置(位置指针), 如果没有找到返回的是空

    获取位置: int position = pos - str;

  • char* pos = strchr(name,'n'); // 返回的是字符第一次出现的位置(位置指针), 如果没有找到返回的是空

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main() {

const char *str = "name not Eastrise";
const char *substr = "E";
char *pos = strstr(str, substr); // 返回的是字符串第一次出现的位置(位置指针),如果没有找到返回的是空
printf("%s\n", pos); // Eastrise;
// 求一下位置 int 怎么办? strstr
int position = pos - str;

printf("第一次出现的位置是:%d\n", position);

// 包含? pos 是不是空就可以了
if (pos)
printf("%s", "包含");
else
printf("%s", "不包含");

getchar();
}

打印结果:

1
2
3
Eastrise
第一次出现的位置是:9
包含

6.字符串复制和拼接

  • strcpy(dst, src); // 复制
  • strcat(dst,src); // 拼接
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int main(){

//strcopy; copy进来
const char* str = "eastrise";

const char* str1 = " is";

// char* str1 = "is";
char cpy[strlen(str)+strlen(str1)];

// str 会 copy 到 cpy 里面
strcpy(cpy,str);

printf("%s\n",cpy);

//拼接
strcat(cpy,str1);

printf("%s",cpy);

getchar();
}

打印结果:

1
2
eastrise
eastrise is

7.手写字符串截取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// 截取
char* substr(const char* str,int start ,int end){
// 开辟一个字符串去存储我们的数据,开辟多大计算
// char sub[end -start];
int len = end - start;
if (len == 0) {
return nullptr;
}
char* sub = (char*)malloc(sizeof(char)*(len+1));// 记得+1,因为还有一个\0,在 NDK 一般会采用静态的数组存储 char sub[len]
// malloc 一定要 free

// 遍历赋值
for(int i = 0; i< len; i++){
sub[i] = str[start+i];
}
// 标记字符串结尾,否则 print 无法判断结尾
sub[len] = '\0';

printf("%p\n",sub);

// free(sub);

return sub;
}

// 字符串的截取
int main(){
const char* str = "Eastrise is";

// 截取第三个位置到第五个位置 3,5
char* sub = substr(str,0,5);

printf("%p\n",sub);

printf("%s",sub);

// 一定要free ,因为你的 substr 有动态开辟内存,但是真正开发中并不会这么做,自己的方法尽量要自己处理好内存
free(sub);

getchar();
}

打印结果:

1
2
3
0000000000B61440
0000000000B61440
Eastr

8.手写字符串小写转换

字符大小写转换

  • tolower(ch); // A->a
  • toupper(ch); // a->A
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <ctype.h>
// dest 用来存放结果, 大小自己指定
// source 需要转换的字符串
void lower(char* dest,const char* source){
while (*source != '\0'){
// 拿当前字符
char ch = *source;
// 转换完成后赋值给 dest
*dest = tolower(ch); // a->a A->a
source++;
dest++;
}
// 标记字符串结尾
*dest = '\0';
}

void upper(char* dest,const char* source){
while (*source != '\0'){
char ch = *source;
*dest = toupper(ch);
source ++;
dest ++;
}

*dest = '\0';
}

9. 手写字符串的替换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
char *substr(const char *str, int start, int end) {
// 开辟一个字符串去存储我们的数据,开辟多大计算
// char sub[end -start];
int len = end - start;
if (len == 0) {
return nullptr;
}
char *sub = (char *) malloc(sizeof(char) * (len + 1));// 记得+1,因为还有一个\0,在 NDK 一般会采用静态的数组存储 char sub[len]
// malloc 一定要 free

// 遍历赋值
for (int i = 0; i < len; i++) {
sub[i] = str[start + i];
}
// 标记字符串结尾,否则 print 无法判断结尾
sub[len] = '\0';

printf("%p\n", sub);

// free(sub);

return sub;
}


char *str_replace(const char *str, const char *src, const char *dst) {
char *pos = strstr(str, src);
if (!pos)
return const_cast<char *>(str);

// 1. 计算新的数组大小
char result[strlen(str) - strlen(src) + strlen(dst)];

// 截取替换
int start_position = pos - str;
char *start = substr(str, 0, start_position);
char *end = substr(str, start_position + strlen(src), strlen(str));

// 拼接
if (start){
strcpy(result, start);
strcat(result, dst);
free(start);
if (end){
strcat(result, end);
free(end);
}
}else{
strcpy(result, dst);
if (end){
strcat(result, end);
free(end);
}
}

return str_replace(result, src, dst);
}

// 字符串替换
int main() {
char *str = str_replace("aabbaabbfffaa", "aa", "ccc");

printf("%s", str);

getchar();
}

打印结果:

1
2
3
4
5
00000000006D1840
00000000006D1860
00000000006D1880
00000000006D18A0
cccbbcccbbfffccc
-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!
0%