我有一个函数,它返回一个用delim
分隔的字符串数组,每次调用strtok
都返回两个分隔符之间的字符串,但不包括分隔符,我希望它只返回字符串末尾为delim
的字符串,如果char==':'
,例如,对于" ici: papa mama"
,如果我用delim== " \t\n:"
调用它,我希望它返回一个数组,其中包含:
ici:
papa
mama
(the':'将包括在ici中,但不包括空格或制表符)。需要帮助吗
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char ** split(const char * str, const char * delim)
{
/* count words */
char * s = strdup(str);
char* inter=malloc(sizeof(char)*100);// pour l etiquette ne pas oublier de mettre deux points a la fin avant de la mettre dans le
if (strtok(s, delim) == 0){
/* no word */
return NULL;}
int nw = 1;
while (strtok(NULL, delim) != 0)
nw += 1;
strcpy(s, str); /* restore initial string modified by strtok */
/* split */
char ** v = malloc((nw + 1) * sizeof(char *));
int i;
v[0] = strdup(strtok(s, delim));
for (i = 1; i != nw; ++i)
v[i] = strdup(strtok(NULL, delim));
v[i] = NULL; /* end mark */
free(s);
return v;
}
int main() {
char **words=split("ici: haha papa", " \t\n:");
printf("%s \n",words[0]);// with the two points
printf("%s \n",words[1]);// without the spaces
printf("%s \n",words[2]);// without the spaces
return 0;
1条答案
按热度按时间oknrviil1#
对于 generalized 解决方案,保留单个分隔符/定界符的唯一方法是编写您自己的标记器。
但是,在***您的特定情况***中,冒号'
:
'似乎只出现在第一个标记的末尾。strtok()
使这类问题变得特别容易,因为您可以在每次调用时更改分隔符/定界符列表。对于剩余的标记,在循环中获取它们,并将冒号包含在分隔符/定界符列表中。
根据您添加的备注:
对于第一个冒号之前可能有多个空格分隔的单词的情况(或者,根据您的注解,冒号没有相邻的空格),您必须使用
strchr()
(或其他搜索函数)来查找令牌,并将字符串的两部分分别送入单独的令牌化循环。错误处理
记住在设计代码时要仔细阅读文档。C语言让你看起来可以把东西很好地链接在一起,但很多时候你不能(没有额外的帮助函数)。例如,
strtok()
可能返回NULL
,这不是strdup()
的有效输入(导致UB)。换句话说,确保使用函数调用的返回值检查错误条件。
更换结构
回到第一个想法,
strtok()
很可能是用strspn()
和strcspn()
函数实现的,而不是用strtok()
,而是用这些函数,再用strndup()
得到想要的子串。更新
我觉得很无聊,所以...这里有一个通用的标记器,它 * 可能 * 做一些你想要的事情...
它用MSVC和Clang干净地编译。在Windows上不要忘记添加
-D_CRT_SECURE_NO_WARNINGS
到您的命令行选项,以沉默的愚蠢。下面是我为它使用的非常简单的测试(只需将其连接到上面的代码并进行编译):