我有一个字符串,我必须从中提取日期。日期的形式是mm / dd / yyyy。所以,首先我用#34; ",当我知道单个令牌是一个日期时,我想在"上使用strtok作为单个令牌。 /"参数。它适用于第一次约会,但在此之后,它无法回到查找由"分隔的令牌。 " (我理解为什么会这样,但我不知道怎么做而不先创建所有日期的字符串数组,我想避免它)
答案 0 :(得分:1)
您可以使用strtok_r
。
您应该为要立即执行的每个单独的标记化声明char*
变量。因此声明一个用于按空格分割,一个用于用斜杠分割。这是strtok
要记住它到底有多远。
将strtok
更改为strtok_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);
}
答案 1 :(得分:0)
除了将完整字符串与日期字符串与strtok_r
分开之外,您可以用来处理任何重入情况的另一种方法是简单地沿着字符串向下走,检查每个字符。您可以使用一对简单的指针轻松地从日期字符串中解析日期组件。您可以使用strchr
来指向日期字符串中的指针位置,或者只需使用循环向下走指针日期字符串并随时前进指针。
(您还可以使用数组索引表示法向下移动字符串的长度,如果您愿意,请string[i]
与i
0
到< length
)
例如,在确认您的日期格式为mm/dd/yyyy
后,使用指针 p
和结束指针 { {1}},您可以拨打ep
两次来查找每个strchr
,并将日期组件复制到您选择存储它们的任何位置。 (下面使用单独的'/'
,m
和d
数组:
y
在某种程度上,您可以使用循环来遍历日期字符串中的每个字符,并执行#include <stdio.h>
#include <string.h>
int main (void) {
const char *dtstr = "mm/dd/yyyy";
char *p = (char *)dtstr, *ep;
char m[3] = "", d[3] = "", y[5] = "";
/* locate 1st '/', copy, validate, advance pointer */
if (!(ep = strchr (p, '/'))) return 1;
if (ep - p < 3 && strncpy (m, p, ep - p)) p = ep + 1;
else return 1;
/* locate 2st '/', copy, validate, advance pointer */
if (!(ep = strchr (p, '/'))) return 1; /* locate 2nd */
if (ep - p < 3 && strncpy (d, p, ep - p)) p = ep + 1;
else return 1;
/* copy final year component */
if (!strncpy (y, p, 5)) return 1;
m[2] = d[2] = y[4] = 0; /* affirmatively nul-terminate */
printf ("\n %s/%s/%s\n\n", m, d, y);
return 0;
}
手动执行的操作。指针名称的唯一区别是strchr
是用于遍历(检查)日期字符串中每个字符的指针,而p
用于写指针(只是一个“只在名义上”改变以帮助明确使用它们。
wp
同样,使用#include <stdio.h>
int main (void) {
const char *dtstr = "mm/dd/yyyy";
char *p = (char *)dtstr, *wp;
char m[3] = "", d[3] = "", y[5] = "";
/* parse each date component with simple pointer and loop */
for (wp = m; *p && *p != '/' && wp - m < 3; p++, wp++) /* mm */
*wp = *p; /* copy to m */
*wp = 0; /* nul-terminate */
for (++p, wp = d; *p && *p != '/' && wp - d < 3; p++, wp++) /* dd */
*wp = *p;
*wp = 0;
for (++p, wp = y; *p && wp - y < 5; p++, wp++) /* year */
*wp = *p;
*wp = 0;
printf ("\n %s/%s/%s\n\n", m, d, y);
return 0;
}
处理完整字符串然后解析日期字符串也没有错,但是你可能会发现一些情况,只需将指针向下移动一个字符串(使用指针)如上所示,或者数组索引表示法,例如strtok/strtok_r
)同样容易,如果不容易的话。使用这种类型的方法,无论你的字符串是如何扭曲的,或者在其中使用了多少个不同的分隔符,你只需编写条件检查并移动指针即可完全控制...
示例使用/输出
在每种情况下,每种方法的输出都是相同的。
datestr[i]
查看方法,指针和$ ./bin/ptrdate
mm/dd/yyyy
。在任何给定的情况下,每个都有其优点/缺点。如果您有任何问题,请告诉我。
答案 2 :(得分:0)
如您所知,strtok()
需要一系列调用才能正常工作。如果只有strtok()
的第一个电话序列适合您,那么最合理的原因是您错过了初始化呼叫&#39;为第二个序列设置不同的分隔符字符串(您必须在空格分隔符和斜杠分隔符之间切换,不是吗?)。
使用循环发布代码将有助于确认。
答案 3 :(得分:0)
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
}