【发布时间】:2013-05-10 09:06:54
【问题描述】:
在下面的程序中,strtok() 在主要部分按预期工作,但我无法理解一个发现背后的原因。我读过关于strtok() 的内容:
为了确定记号的开始和结束,该函数首先从起始位置扫描不包含在分隔符中的第一个字符(它成为记号的开始)。然后从标记的这个开头开始扫描分隔符中包含的第一个字符,这成为标记的结尾。
众所周知,strtok() 在每个标记的末尾放置一个\0。但是在下面的程序中,最后一个定界符是一个点(.),在该点和引号(")之间有Toad。现在点是我程序中的分隔符,但 Toad 之后没有分隔符,甚至没有空格(这是我程序中的分隔符)。请清除由此前提引起的以下混淆:
为什么strtok() 将 Toad 视为标记,即使它不在两个分隔符之间?这是我在遇到 NULL 字符 (\0) 时读到的关于 strtok() 的内容:
一旦在对 strtok 的调用中找到 str 的终止空字符,所有后续以空指针作为第一个参数的函数调用都返回空指针。
没有地方说一旦遇到空字符,就会返回指向标记开头的指针(我们甚至没有标记,因为我们没有得到标记的结尾,因为没有扫描后发现的分隔符从令牌的开头开始(即从 Toad 的“T”开始),我们只找到了一个空字符,不是分隔符)。那么为什么参数字符串的最后一个分隔符和引号之间的部分被strtok()视为标记?请解释一下。
代码:
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] =" Falcon,eagle-hawk..;buzzard,gull..pigeon sparrow,hen;owl.Toad";
char * pch=strtok(str," ;,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ;,.-");
}
return 0;
}
输出:
猎鹰
老鹰
鹰
秃鹰
海鸥
鸽子
麻雀
母鸡
猫头鹰
蟾蜍
【问题讨论】:
-
不确定我是否理解您的问题;你期望什么输出?
Toad不会被打印出来?如果您删除输入字符串中的前导空格,则按照该逻辑,Falcon也不应该被打印。我会说这会导致一些不直观的行为。 -
如果您删除了 Falcon 之前的空白,
strtok()仍会将“Falcon”视为第一个标记。 -
@JonathanLeffler 我是故意这样做的。就像我说的,一切都和
strtok()的预期一样,除了最后一个标记,它显然不在两个分隔符之间。 -
@JonathanLeffler 我很遗憾在发布这个问题后我不得不马上出去。
-
@Praetorian 为什么我不应该期望打印
Falcon?我已经从源中提到the function first scans from the starting location for the first character not contained in delimiters..ie,对于令牌的开头,我们不需要定界符(空格是我程序中的定界符),但是要标记令牌的结尾,我们显然需要一个定界符,并且字符串末尾的NULL不在定界符列表中。