在C语言中,没有内置的字符串(char*)类型直接支持像 str.substr(start, length) 这样的子字符串操作,你需要手动实现这个功能,以下是几种常见的方法:

(图片来源网络,侵删)
方法1:返回动态分配的子字符串(推荐)
这种方法返回一个新分配的字符串,调用者负责释放内存。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 返回动态分配的子字符串,调用者需 free()
char* substring(const char* str, int start, int length) {
if (str == NULL || start < 0 || length < 0) {
return NULL;
}
int len = strlen(str);
if (start >= len) {
return strdup(""); // 返回空字符串
}
// 调整长度,防止越界
if (start + length > len) {
length = len - start;
}
char* sub = (char*)malloc(length + 1); // +1 for '\0'
if (sub == NULL) {
return NULL;
}
strncpy(sub, str + start, length);
sub[length] = '\0';
return sub;
}
int main() {
const char* str = "Hello, World!";
char* sub = substring(str, 7, 5); // 提取 "World"
if (sub != NULL) {
printf("Original: %s\n", str);
printf("Substring: %s\n", sub);
free(sub); // 记得释放内存!
}
return 0;
}
关键点:
- 使用
strdup()或malloc()分配内存,避免返回局部变量(栈内存)。 - 调用者必须
free()返回的字符串,否则会导致内存泄漏。 - 处理边界条件(如
start超出字符串长度或length为负数)。
方法2:直接操作原字符串(不分配新内存)
如果只是临时使用子字符串,可以修改原字符串的终止符 \0 来模拟子字符串,但会破坏原字符串!
#include <stdio.h>
#include <string.h>
// 临时修改原字符串,返回子字符串的起始指针
char* temp_substring(char* str, int start, int length) {
if (str == NULL || start < 0 || length < 0) {
return NULL;
}
int len = strlen(str);
if (start >= len) {
str[0] = '\0';
return str;
}
if (start + length > len) {
length = len - start;
}
char* end = str + start + length;
*end = '\0'; // 临时截断字符串
return str + start;
}
int main() {
char str[] = "Hello, World!"; // 必须是字符数组(可修改)
char* sub = temp_substring(str, 7, 5); // 返回 "World"
printf("Original: %s\n", str); // 原字符串被修改为 "Hello, World"
printf("Substring: %s\n", sub);
// 恢复原字符串(如果需要)
strcpy(str, "Hello, World!");
return 0;
}
缺点:

(图片来源网络,侵删)
- 会修改原字符串,可能影响后续使用。
- 仅适用于临时操作,不推荐用于生产代码。
方法3:使用 strncpy 直接复制到目标缓冲区
如果已有预分配的缓冲区,可以直接复制子字符串。
#include <stdio.h>
#include <string.h>
void copy_substring(const char* src, char* dest, int start, int max_length) {
if (src == NULL || dest == NULL || start < 0) {
return;
}
int len = strlen(src);
if (start >= len) {
dest[0] = '\0';
return;
}
int remaining = len - start;
int copy_len = (remaining < max_length) ? remaining : max_length;
strncpy(dest, src + start, copy_len);
dest[copy_len] = '\0';
}
int main() {
const char* str = "Hello, World!";
char sub[10]; // 预分配足够大的缓冲区
copy_substring(str, sub, 7, 5); // 复制 "World" 到 sub
printf("Substring: %s\n", sub); // 输出 "World"
return 0;
}
优点:
- 无需动态内存管理,避免内存泄漏。
- 适用于已知缓冲区大小的场景。
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 动态分配(方法1) | 安全,不修改原字符串 | 需手动 free() |
需要长期使用子字符串 |
| 临时修改(方法2) | 无需额外内存 | 破坏原字符串 | 临时操作,原字符串可丢弃 |
| 缓冲区复制(方法3) | 无动态内存管理 | 需预分配足够大的缓冲区 | 已知目标缓冲区大小的情况 |
推荐使用方法1,除非有特殊需求。
