C 標準庫沒有 replace 函數。
所以所謂“字符串替換”,本質上都是:
掃描 + 計算長度 + 內存拷貝
C 字符串替換的 3 種常見方式
方式一:生成新字符串
原字符串 = 前段 + src + 後段
新字符串 = 前段 + dst + 後段
- 不修改原字符串
- 需要
malloc - 誰調用,誰
free
函數原型示例:
char* str_replace(const char* str,
const char* src,
const char* dst);
適合:NDK、多線程、不確定原字符串來源(字面量 / 棧 / 堆)
方式二:原地替換(僅限等長)
strlen(src) == strlen(dst)
函數示例:
void str_replace_inplace(char* str,
const char* src,
const char* dst);
- 必須是可寫內存(數組 / malloc)
- 不能擴展或縮短字符串
- 風險高
方式三:調用方提供緩衝區(無 malloc)
函數示例:
int str_replace(const char* str,
const char* src,
const char* dst,
char* out,
size_t out_size);
- 不使用堆
- 不泄漏
- 由調用方控制內存
實現替換的核心步驟
- 查找替換點
char* pos = strstr(str, src);
- 計算新字符串長度
new_len = strlen(str)
- strlen(src)
+ strlen(dst);
- 分配內存
char* result = malloc(new_len + 1);
- 分配內存
memcpy / strcpy / strcat
- 處理
\0,釋放臨時內存
示例:使用方式一
#define _CRT_SECURE_NO_WARNINGS // windows 加上這個 抑制警告!否則不能運行
#include<stdio.h>
#include <cstring>
#include <cstdlib>
// 字符串截取
char* substr(const char* str, int start, int end) {
//開闢一個字符串去存儲我們的數據,開闢多大計算
//char sub[end-start]:
int len = end - start;
char* sub = (char*)malloc(len * sizeof(char) + 1);//記得加上1,在NDK一般會採用靜態的數組存儲charsub[len]
// malloc 一定要 free
//遍歷賦值
str += start;
for (int i = 0; i < len; i++) {
sub[i] = *str;
str++;//指針往後挪一位
}
//標記字符串結尾,否則print無法判斷結尾
sub[len] = '\0';
printf("%p\n", sub);
// free(sub):
return sub;
}
// 字符串替換
char* str_replace(char* str,const char* src, const char* dst) {
// 1. 有沒有 aa
char* pos = strstr(str, src); // 返回的是字符串第一次出現的位置(位置指針),如果沒有找到返回的是空
if (!pos) {
return str;
}
// 2. 計算新字符串的長度, 比如 aa 替換為 ccc = 原來數組的大小 - 被替換的大小 + 替換的大小
int newArrSize = strlen(str) - strlen(src) + strlen(dst);
// 開闢一個新的數組來存放
// char* result[newArrSize]; AS 裏面這樣寫行,這裏不行
char* result = (char*)malloc(sizeof(char) * (newArrSize + 1)); // +1 是為了存放結束符
// 3. 進行拼接 aabbcc, bb->fff, aafffcc
int start_end_position = pos - str; // 計算出 pos 在 str 中的偏移位置
// 先拿aa
char* start = substr(str, 0, start_end_position); // 從0開始,到pos位置結束
// 中間的字符串 fff dst
// 最後的字符串 cc
int end_start_position = start_end_position + strlen(src); // 計算出結束位置
char* end = substr(str, end_start_position, strlen(str));
// 拼接
strcpy(result, start); // 先拼接開始的字符串
strcat(result, dst); // 拼接中間的字符串
strcat(result, end); // 拼接結尾的字符串
free(start);
free(end);
// 4. 多個替換?while循環,遞歸
return result; // 這裏只替換了一個
}
// 字符串替換
int main() {
// aabbaabbaabb , aa 替換為 cc
char str1[] = "aabbaabbaabb";
char* str = str_replace(str1,"aa","ccc");
printf("str_replace: %s\n", str);
free(str);
return 0;
}
運行結果(只替換了一次):
str_replace: cccbbaabbaabb