C语言中的strtok函数

C语言中的strtok函数,c,strtok,C,Strtok,我有一个字符串,我必须从中提取日期。日期的形式为mm/dd/yyyy。因此,首先我用“”分隔令牌,当我知道单个令牌是日期时,我想在带有“/”参数的单个令牌上使用strtok。它对于第一个日期非常有效,但之后就无法返回到查找以“”分隔的令牌(我理解为什么会发生这种情况,但我不知道如何在不首先创建所有日期的字符串数组的情况下进行此操作,我希望避免此操作)您可以使用 您应该为要立即执行的每个单独的标记化声明一个char*变量。因此,声明一个用于按空格拆分,另一个用于按斜线拆分。这是为了让strtok记

我有一个字符串,我必须从中提取日期。日期的形式为mm/dd/yyyy。因此,首先我用“”分隔令牌,当我知道单个令牌是日期时,我想在带有“/”参数的单个令牌上使用strtok。它对于第一个日期非常有效,但之后就无法返回到查找以“”分隔的令牌(我理解为什么会发生这种情况,但我不知道如何在不首先创建所有日期的字符串数组的情况下进行此操作,我希望避免此操作)

您可以使用

您应该为要立即执行的每个单独的标记化声明一个
char*
变量。因此,声明一个用于按空格拆分,另一个用于按斜线拆分。这是为了让strtok记住它走了多远

strtok
更改为
strtok\u r
,并将其中一个变量的地址作为新的最后一个参数传递

大概是这样的:

char *spaceSplitState;
char *spaceToken = strtok_r(myString, " ", &spaceSplitState);
while(spaceToken)
{
    char *slashSplitState;
    char *slashToken = strtok_r(spaceToken, "/", &slashSplitState);
    while(slashToken)
    {
        // do something
        slashToken = strtok_r(myString, "/", &slashSplitState);
    }
    spaceToken = strtok_r(NULL, " ", &spaceSplitState);
}

除了用
strtok_r
分隔完整字符串和日期字符串外,处理任何重入情况的另一种方法是,只需沿着字符串向下移动指针,边走边检查每个字符。一旦用一对简单的指针隔离,就可以轻松地从日期字符串解析日期组件。您可以使用
strchr
在日期字符串中确定指针位置的方向,也可以使用循环沿日期字符串向下移动指针,并在移动过程中向前移动指针

(如果您愿意,也可以使用数组索引符号向下移动字符串的长度,例如
string[i]
,将
i
0
移动到

例如,在您确认有
mm/dd/yyyy
格式的日期后,使用指针
p
和结束指针
ep
,您可以对
strchr
进行两次调用,以查找每个
“/”
,并将日期组件复制到您选择存储它们的任何位置。(下面使用单独的
m
d
y
数组):

同样,使用
strtok/strtok_r
解析完整字符串,然后解析日期字符串也没有什么错,但是您可能会发现,在许多情况下,简单地将指针向下移动字符串(或者使用如上所示的指针,或者数组索引符号,例如
datestr[i]
)同样简单,如果不容易的话。使用此类型方法,不管字符串有多扭曲,也不管其中使用了多少不同的分隔符,只要编写条件检查并移动指针,就可以完全控制

示例使用/输出

在每种情况下,每种方法的输出都是相同的

$ ./bin/ptrdate

 mm/dd/yyyy
查看这两种方法、指针和strtok
。在任何特定情况下,每种方法都有其优点/缺点。如果您有任何问题,请告诉我。

如您所知,
strtok()
需要一系列调用才能工作。如果只有对strtok()的第一个调用序列对您有效,最合理的原因是您错过了为第二个序列设置不同分隔符字符串的“初始化调用”(您必须在空格分隔符和斜杠分隔符之间交替,不是吗?)。

在循环中发布代码将有助于确认这一点。

根据我的说法,简短而简单的程序是
The short and simple program according to me would be

        #include<string.h>
        #include<stdio.h>
void main()
{
char date[15];
char *dd,*mm,*yy;
gets(date);
char *token=strtok(date,"\");
dd=token;  //you get the date
token=strtok(NULL,"\");
mm=token; //you get the month
token=strtok(NULL,"\");
yy=token; //you get the year
}
#包括 #包括 void main() { 字符日期[15]; 字符*dd,*mm,*yy; 获取(日期); char*token=strtok(日期,“\”); dd=token;//您可以得到日期 令牌=strtok(空,“\”; mm=token;//您可以得到月份 令牌=strtok(空,“\”; yy=token;//你得到了年份 }
你能使用strtok_r()吗?@Dmitri:问题甚至没有说明它是多线程的。strtok_r不是C标准,而是POSIX。@Olaf是这样吗?这有什么关系呢?如果你有strtok_r(就像在Linux上一样),你可以同时在多个字符串上调用它,这样你就可以strtok_r表示“”的字符串,然后strtok r表示“/”的结果来获得片段。如果没有strtok_r,我想不出什么聪明的方法,除非你自己编译它。如果
strtok_r()
不是一个选项,你也可以通过传递一个指向超过日期标记的位置的指针作为
strtok()的第一个参数来重新开始搜索“”
$ ./bin/ptrdate

 mm/dd/yyyy
The short and simple program according to me would be

        #include<string.h>
        #include<stdio.h>
void main()
{
char date[15];
char *dd,*mm,*yy;
gets(date);
char *token=strtok(date,"\");
dd=token;  //you get the date
token=strtok(NULL,"\");
mm=token; //you get the month
token=strtok(NULL,"\");
yy=token; //you get the year
}