C语言固定接口下不修改原字符串的字符串分割函数实现问询
嘿,我来帮你搞定这个学校作业的字符串分割函数!先把需求再理一遍:我们要实现一个固定原型的函数,把传入的原始字符串按指定分隔符拆成不含分隔符的子串,存到result二维数组里,同时用size指针记录最终的子串数量。
先给你补全并优化后的完整实现,然后我再拆解关键细节:
#include <string.h> void stringSplit(const char *original, char result[50][256], int* size, char delim){ size_t begin = 0; // 先初始化子串数量为0,避免传入的size有垃圾值 *size = 0; // 空指针直接返回 if(!original){ return; } // 提前计算字符串长度,避免循环里反复调用strlen(效率低) size_t len = strlen(original); for(size_t i=0; i<len; i++ ){ if (original[i] == delim) { // 先检查是否还有空间存子串(最多50个),防止数组越界 if (*size >= 50) { break; } // 计算当前子串的长度 size_t sub_len = i - begin; // 这里可以根据需求调整:如果要保留连续分隔符之间的空串,就删掉这个判断 if (sub_len > 0) { // 复制子串到result数组 strncpy(result[*size], original + begin, sub_len); // 手动加结束符,因为strncpy不会自动补全(当子串长度等于指定长度时) result[*size][sub_len] = '\0'; // 子串数量+1 (*size)++; } // 更新下一个子串的起始位置 begin = i + 1; } } // 处理最后一段子串(如果原始字符串不以分隔符结尾) if (*size < 50 && begin < len) { size_t sub_len = len - begin; // 确保子串不超过单个元素的最大容量(255字符+结束符) if (sub_len > 255) { sub_len = 255; } strncpy(result[*size], original + begin, sub_len); result[*size][sub_len] = '\0'; (*size)++; } }
关键细节解释:
- 初始化
size:必须先把*size设为0,不然传入的指针可能指向一个不确定的数值,导致统计错误。 - 提前计算字符串长度:
strlen是遍历整个字符串的操作,如果在循环里每次调用,时间复杂度会从O(n)变成O(n²),提前存起来效率更高。 - 数组越界防护:
result最多只能存50个子串,每个子串最多255个字符(加结束符),所以必须检查这两个边界,避免缓冲区溢出(这是C语言里很重要的安全点)。 - 空串处理:代码里的
if(sub_len > 0)是为了跳过连续分隔符产生的空串(比如"a,,b"里的两个逗号之间的空内容)。如果你的作业要求保留这种空串,直接删掉这个判断就行。 - 手动添加结束符:
strncpy不会自动在目标字符串末尾加'\0',如果我们复制的子串长度刚好等于sub_len,就会导致字符串没有结束符,后续使用时会出现乱码,所以必须手动补上。
测试示例(可以用来验证功能):
#include <stdio.h> int main() { const char* test_str = "apple,banana,orange,,grape"; char res[50][256]; int count = 0; stringSplit(test_str, res, &count, ','); printf("分割得到%d个子串:\n", count); for(int i=0; i<count; i++){ printf("第%d个:%s\n", i+1, res[i]); } return 0; }
如果保留空串的话,输出会是:
分割得到5个子串: 第1个:apple 第2个:banana 第3个:orange 第4个: 第5个:grape
如果删掉空串判断,就会得到4个子串,跳过中间的空内容。
内容的提问来源于stack exchange,提问作者Adrian Grupaty Chlpik
相关产品推荐
相关产品推荐

