如果我有一个字符串:Hi:my:name:is:lacrosse1991:
我如何使用strtok
只检索is
(换句话说第四个字段)?这类似于你在bash中使用cut的方式,我只会cut -d ":" -f 4
。如果这是一个错误的功能做这样的事情,请让我知道,任何帮助非常感谢,谢谢! (我刚刚开始自学C语,如果这些是我要求的明显问题,我会提前道歉)
这是我将使用的剪切命令的示例
x=$(echo "$death" | cut -d ':' -f 4)
y=$(echo "$death" | cut -d ':' -f 5)
z=$(echo "$death" | cut -d ':' -f 6)
答案 0 :(得分:6)
如果你知道它是第4个字段,你只需要调用strtok()4次 - 没有扫描整个字符串就无法跳到第4个字段(这就是strtok正在做的事情)
答案 1 :(得分:1)
提取N
字段的一种方法(在调用后保持字符串处于原始状态)是使用以下getFld
函数。首先,必要的标题:
#include <stdio.h>
#include <string.h>
#include <malloc.h>
现在功能本身,我希望记录得足够好:
char *getFld (char *srchStr, char delim, int numFld) {
char *copyStr, *retStr, *tmpStrPtr, delims[2];
// Make a copy so as to not damage original.
if ((copyStr = strdup (srchStr)) == NULL) return NULL;
// Create delimiter string from character.
delims[0] = delim; delims[1] = '\0';
retStr = NULL;
// Start loop, extracting fields.
tmpStrPtr = strtok (copyStr, delims);
while (tmpStrPtr != NULL) {
// If this is the field we want, make a copy.
if (numFld == 0) retStr = strdup (tmpStrPtr);
// Get next field.
tmpStrPtr = strtok (NULL, delims);
numFld--;
}
// Clean up, return field copy (must be freed eventually) or NULL.
free (copyStr);
return retStr;
}
最后,它的测试程序:
int main (void) {
int i = 0;
char str[] = "Hi:my:name:is:lacrosse1991";
char *fld;
while ((fld = getFld (str, ':', i)) != NULL) {
printf ("Field %d is '%s'\n", i, fld);
free (fld);
i++;
}
return 0;
}
编译并运行它后,我得到:
Field 0 is 'Hi'
Field 1 is 'my'
Field 2 is 'name'
Field 3 is 'is'
Field 4 is 'lacrosse1991'
现在,请注意strdup
不是标准C,但如果您的实施没有,则可以使用this one。您可能还希望更改strdup
失败时的行为,因为无法将当前案例与超出范围字段区分开来。
但是,这段代码应该可以作为开始时的基线。
答案 2 :(得分:1)
为此目的,我会避免strtok
(就此而言,大多数其他人)。在这种情况下,我认为我只会使用sscanf
进行scanset
转换:
char field_four[128];
sscanf(input_string, "%*[^:]:%*[^:]:%*[^:]:%127[^:]:", field_four);
在此,我们首先重复%*[^:]:
三次。每个都读取一个字符串,包括除冒号之外的任何字符,然后是冒号。 *
表示应从输入中读取,但忽略(未分配给任何内容)。然后,对于第四个字段,我们有相同的东西,除了我们不包含*
,以便字段 被分配,在本例中为{ {1}}(虽然你显然应该使用更有意义的名字)。
对于第四个字段,我还添加了最大长度的规范。由于field_four
始终包含sscanf
来终止字符串,但不包括在计数中,我们需要指定一个小于缓冲区大小的大小。