You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

字符串分割为X个子串的方法修复:解决截断丢失数据问题

嘿,我完全懂你遇到的麻烦——当字符串长度没法被X整除时,直接按固定长度分割会把末尾的字符丢掉,太闹心了!咱们来把这个问题搞定。

首先,我先猜一下你可能的错误实现逻辑:大概率是直接把字符串长度除以X得到每个子串的固定长度,然后循环截取,最后一段不够这个长度就直接忽略剩余字符了?比如类似这样的代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char** split_string(char* text, int num_parts) {
    int len = strlen(text);
    int part_len = len / num_parts;
    char** result = malloc(num_parts * sizeof(char*));
    
    for (int i = 0; i < num_parts; i++) {
        result[i] = malloc(part_len + 1);
        strncpy(result[i], text + i * part_len, part_len);
        result[i][part_len] = '\0';
    }
    return result;
}

这个代码的问题很明显:当len % num_parts != 0时,len - num_parts*part_len个字符会被直接丢弃,因为最后一段只截取了part_len长度,剩下的字符没被处理。

下面给你两种修复方案,你可以根据需求选:

修复方案1:均匀分配字符(无截断)

这个方案会让前len%num_parts个子串多包含一个字符,剩下的子串保持基础长度,这样所有字符都会被分配,且各子串长度差异最小。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char** split_string(char* text, int num_parts) {
    if (num_parts <= 0) return NULL; // 处理非法输入,避免崩溃
    
    int len = strlen(text);
    int base_len = len / num_parts; // 每个子串的基础长度
    int extra = len % num_parts;    // 需要多一个字符的子串数量
    
    // 分配存储子串指针的数组
    char** result = malloc(num_parts * sizeof(char*));
    if (!result) return NULL; // 内存分配失败,直接返回
    
    int current_pos = 0;
    for (int i = 0; i < num_parts; i++) {
        // 前extra个子串长度+1,其余用基础长度
        int current_part_len = base_len + (i < extra ? 1 : 0);
        
        // 分配当前子串的内存
        result[i] = malloc(current_part_len + 1);
        if (!result[i]) {
            // 内存分配失败时,要释放已经分配的内存,避免泄漏
            for (int j = 0; j < i; j++) free(result[j]);
            free(result);
            return NULL;
        }
        
        // 截取子串并添加结束符
        strncpy(result[i], text + current_pos, current_part_len);
        result[i][current_part_len] = '\0';
        
        // 更新当前截取位置
        current_pos += current_part_len;
    }
    return result;
}

// 测试用例
int main() {
    char text[] = "this is a string used as an example";
    int num_parts = 5;
    char** parts = split_string(text, num_parts);
    
    if (parts) {
        printf("分割结果:\n");
        for (int i = 0; i < num_parts; i++) {
            printf("[%d]: %s\n", i, parts[i]);
            free(parts[i]); // 记得释放每个子串的内存
        }
        free(parts); // 最后释放指针数组的内存
    }
    return 0;
}

修复方案2:最后一段包含剩余所有字符

如果你不需要均匀分配,只想保证前X-1段是固定长度,最后一段包含所有剩余字符,这个方案更简单:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char** split_string(char* text, int num_parts) {
    if (num_parts <= 0) return NULL;
    
    int len = strlen(text);
    int base_len = len / num_parts;
    
    char** result = malloc(num_parts * sizeof(char*));
    if (!result) return NULL;
    
    int current_pos = 0;
    // 处理前num_parts-1个固定长度的子串
    for (int i = 0; i < num_parts - 1; i++) {
        result[i] = malloc(base_len + 1);
        if (!result[i]) {
            // 内存分配失败,清理已分配的内存
            for (int j = 0; j < i; j++) free(result[j]);
            free(result);
            return NULL;
        }
        strncpy(result[i], text + current_pos, base_len);
        result[i][base_len] = '\0';
        current_pos += base_len;
    }
    
    // 最后一个子串取剩下的所有字符
    int last_part_len = len - current_pos;
    result[num_parts - 1] = malloc(last_part_len + 1);
    if (!result[num_parts - 1]) {
        for (int j = 0; j < num_parts - 1; j++) free(result[j]);
        free(result);
        return NULL;
    }
    strncpy(result[num_parts - 1], text + current_pos, last_part_len);
    result[num_parts - 1][last_part_len] = '\0';
    
    return result;
}

注意事项

  • 一定要记得内存管理:使用完分割后的子串数组后,要先逐个free每个子串的内存,再free存储指针的数组,避免内存泄漏。
  • 代码里加入了非法输入(比如num_parts<=0)和内存分配失败的处理,能让程序更健壮。

内容的提问来源于stack exchange,提问作者user6793527

火山引擎 最新活动