方法 1:使用 strncpy 和 strcat 手动替换
这种方法的基本思路是:

(图片来源网络,侵删)
- 找到子字符串的起始位置。
- 将子字符串之前的部分复制到新字符串中。
- 将替换字符串复制到新字符串中。
- 将子字符串之后的部分复制到新字符串中。
代码示例
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* replaceSubstring(const char* str, const char* oldSub, const char* newSub) {
// 1. 检查输入是否有效
if (str == NULL || oldSub == NULL || newSub == NULL) {
return NULL;
}
// 2. 计算字符串长度
size_t strLen = strlen(str);
size_t oldLen = strlen(oldSub);
size_t newLen = strlen(newSub);
if (oldLen == 0) {
return strdup(str); // oldSub 为空,直接返回原字符串的副本
}
// 3. 计算新字符串的最大可能长度
size_t maxNewLen = strLen - oldLen + newLen + 1;
// 4. 分配内存
char* result = (char*)malloc(maxNewLen);
if (result == NULL) {
return NULL;
}
// 5. 查找子字符串
const char* found = strstr(str, oldSub);
if (found == NULL) {
strcpy(result, str); // 如果没找到,直接返回原字符串
return result;
}
// 6. 复制子字符串之前的部分
size_t beforeLen = found - str;
strncpy(result, str, beforeLen);
result[beforeLen] = '\0';
// 7. 拼接替换字符串
strcat(result, newSub);
// 8. 拼接子字符串之后的部分
strcat(result, found + oldLen);
return result;
}
int main() {
const char* str = "Hello, world! Welcome to the world of C programming.";
const char* oldSub = "world";
const char* newSub = "universe";
char* replaced = replaceSubstring(str, oldSub, newSub);
if (replaced != NULL) {
printf("Original: %s\n", str);
printf("Replaced: %s\n", replaced);
free(replaced); // 记得释放内存
}
return 0;
}
输出
Original: Hello, world! Welcome to the world of C programming.
Replaced: Hello, universe! Welcome to the universe of C programming.
方法 2:逐个字符替换(适用于单字符替换)
如果只是替换单个字符(而不是子字符串),可以使用更简单的方法:
代码示例
#include <stdio.h>
#include <string.h>
void replaceChar(char* str, char oldChar, char newChar) {
if (str == NULL) {
return;
}
for (int i = 0; str[i] != '\0'; i++) {
if (str[i] == oldChar) {
str[i] = newChar;
}
}
}
int main() {
char str[] = "Hello, world! Welcome to the world of C programming.";
replaceChar(str, 'o', 'O');
printf("Replaced: %s\n", str);
return 0;
}
输出
Replaced: HellO, wOrld! WelcOme tO the wOrld Of C prOgramming.
方法 3:使用 sprintf 动态分配内存(适用于多次替换)
如果字符串中可能出现多次子字符串,可以循环替换:
代码示例
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* replaceAll(const char* str, const char* oldSub, const char* newSub) {
if (str == NULL || oldSub == NULL || newSub == NULL) {
return NULL;
}
size_t oldLen = strlen(oldSub);
size_t newLen = strlen(newSub);
size_t strLen = strlen(str);
if (oldLen == 0) {
return strdup(str);
}
// 计算新字符串的最大可能长度
size_t maxNewLen = strLen + 1; // 初始估计
char* result = (char*)malloc(maxNewLen);
if (result == NULL) {
return NULL;
}
const char* src = str;
char* dest = result;
while (1) {
const char* found = strstr(src, oldSub);
if (found == NULL) {
strcpy(dest, src);
break;
}
// 复制子字符串之前的部分
size_t beforeLen = found - src;
strncpy(dest, src, beforeLen);
dest += beforeLen;
// 拼接替换字符串
strcpy(dest, newSub);
dest += newLen;
src = found + oldLen;
}
return result;
}
int main() {
const char* str = "world world world";
const char* oldSub = "world";
const char* newSub = "earth";
char* replaced = replaceAll(str, oldSub, newSub);
if (replaced != NULL) {
printf("Original: %s\n", str);
printf("Replaced: %s\n", replaced);
free(replaced);
}
return 0;
}
输出
Original: world world world
Replaced: earth earth earth
注意事项
- 内存管理:使用
malloc分配的内存必须用free释放,避免内存泄漏。 - 字符串长度:确保新字符串不会超出分配的内存空间。
- 空指针检查:始终检查输入指针是否为
NULL,避免程序崩溃。 strstr的局限性:strstr只能查找第一个匹配项,如果需要全局替换,需要循环调用。
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
方法 1(strncpy + strcat) |
替换第一次出现的子字符串 | 简单直接 | 只能替换第一次出现 |
| 方法 2(逐个字符替换) | 替换单个字符 | 高效 | 不适用于子字符串 |
| 方法 3(循环替换) | 替换所有出现的子字符串 | 全局替换 | 代码稍复杂 |
选择合适的方法取决于你的具体需求,如果只是简单替换,方法 1 足够;如果需要全局替换,方法 3 更合适。

(图片来源网络,侵删)
