C语言字符串分割如何实现?

99ANYc3cd6
预计阅读时长 14 分钟
位置: 首页 C语言 正文

在C语言中,没有内置的字符串分割函数(如Python的split()或Java的split()),但我们可以手动实现一个字符串分割函数,以下是几种实现方式,从简单到复杂,并附有详细解释。

c语言 string split
(图片来源网络,侵删)

方法1:使用strtok函数(标准库方法)

strtok是C标准库<string.h>提供的函数,用于分割字符串,它会修改原字符串(用\0替换分隔符),并且不是线程安全的。

示例代码

#include <stdio.h>
#include <string.h>
int main() {
    char str[] = "apple,banana,orange,grape";
    const char *delim = ","; // 分隔符
    char *token;
    // 第一次调用,传入字符串和分隔符
    token = strtok(str, delim);
    while (token != NULL) {
        printf("%s\n", token);
        // 后续调用,传入NULL,表示继续分割上一次的字符串
        token = strtok(NULL, delim);
    }
    return 0;
}

输出

apple
banana
orange
grape

注意事项

  1. strtok会修改原字符串(用\0替换分隔符)。
  2. 如果需要保留原字符串,可以先复制一份再分割。
  3. strtok不是线程安全的(多线程环境下可能有问题)。
  4. 连续的分隔符会被视为一个分隔符("a,,b" 会被分割成 "a""b")。

方法2:手动实现字符串分割(不修改原字符串)

如果不想修改原字符串,或者需要更灵活的控制(如处理连续分隔符、转义字符等),可以手动实现分割函数。

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 分割字符串,返回动态分配的字符串数组
char** split_string(const char *str, const char *delim, int *count) {
    if (str == NULL || delim == NULL) {
        *count = 0;
        return NULL;
    }
    // 计算分割后的子串数量
    int delim_len = strlen(delim);
    int temp_count = 0;
    const char *p = str;
    while ((p = strstr(p, delim)) != NULL) {
        temp_count++;
        p += delim_len;
    }
    *count = temp_count + 1; // 最后一个子串后面没有分隔符
    // 分配内存存储子串指针
    char **result = (char**)malloc((*count) * sizeof(char*));
    if (result == NULL) {
        *count = 0;
        return NULL;
    }
    // 逐个分割子串
    p = str;
    for (int i = 0; i < *count; i++) {
        const char *next_delim = strstr(p, delim);
        int len;
        if (next_delim == NULL) {
            len = strlen(p);
        } else {
            len = next_delim - p;
        }
        // 分配内存并复制子串
        result[i] = (char*)malloc(len + 1);
        strncpy(result[i], p, len);
        result[i][len] = '\0';
        if (next_delim == NULL) {
            break;
        }
        p = next_delim + delim_len;
    }
    return result;
}
// 释放分割后的内存
void free_split_result(char **result, int count) {
    if (result == NULL) return;
    for (int i = 0; i < count; i++) {
        free(result[i]);
    }
    free(result);
}
int main() {
    const char *str = "apple,banana,orange,grape";
    const char *delim = ",";
    int count;
    char **tokens = split_string(str, delim, &count);
    if (tokens != NULL) {
        for (int i = 0; i < count; i++) {
            printf("%s\n", tokens[i]);
        }
        free_split_result(tokens, count);
    }
    return 0;
}

输出

apple
banana
orange
grape

特点

  1. 不修改原字符串:使用strncpy复制子串。
  2. 动态内存管理:调用者需要手动释放内存(free_split_result)。
  3. 支持任意分隔符(如 或 "->")。
  4. 处理连续分隔符"a,,b" 会被分割成 "a" 和 和 "b")。

方法3:使用strtok_r(线程安全版本)

如果需要线程安全的分割,可以使用POSIX标准提供的strtok_r(非Windows平台可用)。

示例代码

#include <stdio.h>
#include <string.h>
int main() {
    char str[] = "apple,banana,orange,grape";
    const char *delim = ",";
    char *token;
    char *saveptr; // 用于保存上下文
    // 第一次调用,传入字符串和分隔符
    token = strtok_r(str, delim, &saveptr);
    while (token != NULL) {
        printf("%s\n", token);
        // 后续调用,传入NULL和saveptr
        token = strtok_r(NULL, delim, &saveptr);
    }
    return 0;
}

输出

apple
banana
orange
grape

特点

  1. 线程安全:通过saveptr保存上下文,避免多线程冲突。
  2. 仍然修改原字符串(用\0替换分隔符)。

方法 是否修改原字符串 线程安全 适用场景
strtok 简单分割,单线程
手动实现 需要保留原字符串,或复杂逻辑
strtok_r 多线程环境

推荐选择

  • 如果只是简单分割且不关心线程安全,用strtok
  • 如果需要保留原字符串或更灵活的控制,手动实现。
  • 如果是多线程环境,用strtok_r(POSIX平台)。

希望这能帮到你!如果有更具体的需求(如处理转义字符、空格分割等),可以进一步优化代码。

c语言 string split
(图片来源网络,侵删)
-- 展开阅读全文 --
头像
织梦format=html5是什么?
« 上一篇 2025-12-16
dede文档html默认保存路径在哪设置?
下一篇 » 2025-12-16

相关文章

取消
微信二维码
支付宝二维码

目录[+]