在C中拆分字符串以识别连续的制表符
我有一个文件,其中某些字段由选项卡分隔。始终会有17个选项卡,但顺序可能会有所不同,例如在C中拆分字符串以识别连续的制表符,c,strtok,C,Strtok,我有一个文件,其中某些字段由选项卡分隔。始终会有17个选项卡,但顺序可能会有所不同,例如 75104\tDallas\t85\t34.46\t45.64 75205\tHouston\t\t37.34\t87.32 93434\t\t\t1.23\t3.32 当我以以下方式使用strtok时 while (fgets(buf, sizeof(buf), fp) != NULL) { tok = strtok(buf,"\t"); while(tok != NULL)
75104\tDallas\t85\t34.46\t45.64
75205\tHouston\t\t37.34\t87.32
93434\t\t\t1.23\t3.32
当我以以下方式使用strtok时
while (fgets(buf, sizeof(buf), fp) != NULL) {
tok = strtok(buf,"\t");
while(tok != NULL) {
printf("%s->",tok);
tok = strtok(NULL,"\t");
}
}
我获得了所有令牌,但忽略了双制表符\t\t
或更多。但是,我需要知道当一个字段为空时,我不能让strtok忽略多个选项卡,因为结构取决于17个选项卡的计数,如果字段为空,则使用占位符
我已经试着用一种方法来处理这个问题
if(tok == NULL || '')
但是我不认为strtok能在一个标签之后识别一个标签。处理此问题的最佳方法是什么?您不能在您的案例中使用strtok。 从
man strtok:
函数的作用是:将字符串分解为零或更多的序列
非空代币
...
根据以上描述,可以得出两个或更多的序列
已解析字符串中的连续分隔符字节被视为
单个分隔符,并且该分隔符位于
字符串被忽略。换句话说:strtok()返回的令牌
总是非空字符串。因此,例如,给定字符串
“aaa;;bbb”,连续调用strtok()以指定分隔符
字符串“;,”将返回字符串“aaa”和“bbb”,然后返回空值
指针
因此,您必须找到一种替代方法,可以手动编写一个使用线性搜索和strncpy
的函数,或者sscanf
或使用strep
,如果可用的话。后者很可能是我的选择,因为它是用来取代斯特托克的
从man strep:
引入strep()函数是为了替换strtok(3),
因为后者不能处理空字段。然而,strtok(3)公司
表单转换为C89/C99,因此更便于携带
下面是一个使用
strep
的解决方案,它的引入是为了解决strtok
跳过连续分隔符的问题:
char *cur, *nxt;
while (fgets(buf, sizeof(buf), fp) != NULL)
{
nxt = buf;
while ((cur = strsep(&nxt, "\t")) != NULL)
{
printf("%s->",cur);
}
}
注意:传递给strep的字符串必须是可写的(传递文本字符串不起作用)。它将被
strep
修改(在连续调用时,分隔符将被NUL字符覆盖)。这是一个很好的开始理解如何实现这一点的方法,下面的函数将实现这一点,请阅读:
int splitLine(char *buf, char **argv, int max_args)
{
int arg;
/* skip over initial spaces */
while (isspace(*buf)) buf++;
for (arg = 0; arg < max_args
&& *buf != '\0'; arg++) {
argv[arg] = buf;
/* skip past letters in word */
while (*buf != '\0'
&& !isspace(*buf)) {
buf++;
}
/* if not at line's end, mark
* word's end and continue */
if (*buf != '\0') {
*buf = '\0';
buf++;
}
/* skip over extra spaces */
while (isspace(*buf)) buf++;
}
return arg;
}
int分割线(char*buf,char**argv,int max_args)
{
int-arg;
/*跳过初始空格*/
而(isspace(*buf))buf++;
对于(arg=0;arg
此函数使用空格分隔符,您可以重新实现以使用任何其他分隔符。观察它-如果(tok==NULL | |“”)尝试看起来您已经习惯了另一种语言,请查看您的
。它在技术上是有效的C语言,但几乎肯定不是您想要做的。构建一个状态机和/或使用strspn()/strcspn()。下面是strep()
的一个简单实现,如果它还不是工具链的一部分,您可以使用它: