我在想,如何将一个字符串按照分隔符(比如空格)分成2个部分,并将这2个部分分别赋值给2个不同的字符串。我尝试使用 strtok()
函数,但没有成功。
#include <string.h>
char *token;
char line[] = "SEVERAL WORDS";
char *search = " ";
// Token will point to "SEVERAL".
token = strtok(line, search);
// Token will point to "WORDS".
token = strtok(NULL, search);
请注意,在某些操作系统上,strtok
的手册页中提到:
此接口已被
strsep(3)
取代。
下面是使用strsep
的示例:
char* token;
char* string;
char* tofree;
string = strdup("abc,def,ghi");
if (string != NULL) {
tofree = string;
while ((token = strsep(&string, ",")) != NULL)
{
printf("%s\n", token);
}
free(tofree);
}
strtok()
修改了它的输入,所以在字符串常量上使用它是不好的行为(也称未定义行为)。 - John Bodechar *line = "SEVERAL WORDS"
改为 char line[] = "SEVERAL WORDS"
,一切都会就绪。 - Fred Larsonsizeof(arr)/sizeof(arr[0])
的工作原理。 - David Thornleystrtok()
被弃用了?哇!strsep()
甚至不是标准的 C 函数。 - pmg为了这样的目的,我倾向于使用strtok_r()而不是strtok()。
例如...
int main (void) {
char str[128];
char *ptr;
strcpy (str, "123456 789asdf");
strtok_r (str, " ", &ptr);
printf ("'%s' '%s'\n", str, ptr);
return 0;
}
这将输出...
'123456' '789asdf'
如果需要更多的分隔符,那么可以使用循环。
希望这可以帮到你。
char *line = strdup("user name"); // don't do char *line = "user name"; see Note
char *first_part = strtok(line, " "); //first_part points to "user"
char *sec_part = strtok(NULL, " "); //sec_part points to "name"
strtok
会修改字符串,所以不要将其指向字符串字面量的指针传递给它。#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
'\0'
,然后将一个新的char *指针指向新插入的'\0'
之后的位置。这会破坏原始字符串,具体取决于您放置'\0'
的位置。 strtok()
的函数(来自{{link1:一个名为zString的C语言字符串处理库,采用BSD许可证}})。 strtok()
在识别连续分隔符的方式上有所不同,而标准的 strtok()
则不会这样做。char *zstring_strtok(char *str, const char *delim) {
static char *static_str=0; /* var to store last address */
int index=0, strlength=0; /* integers for indexes */
int found = 0; /* check if delim is found */
/* delimiter cannot be NULL
* if no more char left, return NULL as well
*/
if (delim==0 || (str == 0 && static_str == 0))
return 0;
if (str == 0)
str = static_str;
/* get length of string */
while(str[strlength])
strlength++;
/* find the first occurance of delim */
for (index=0;index<strlength;index++)
if (str[index]==delim[0]) {
found=1;
break;
}
/* if delim is not contained in str, return str */
if (!found) {
static_str = 0;
return str;
}
/* check for consecutive delimiters
*if first char is delim, return delim
*/
if (str[0]==delim[0]) {
static_str = (str + 1);
return (char *)delim;
}
/* terminate the string
* this assignmetn requires char[], so str has to
* be char[] rather than *char
*/
str[index] = '\0';
/* save the rest of the string */
if ((str + index + 1)!=0)
static_str = (str + index + 1);
else
static_str = 0;
return str;
}
Example Usage
char str[] = "A,B,,,C";
printf("1 %s\n",zstring_strtok(s,","));
printf("2 %s\n",zstring_strtok(NULL,","));
printf("3 %s\n",zstring_strtok(NULL,","));
printf("4 %s\n",zstring_strtok(NULL,","));
printf("5 %s\n",zstring_strtok(NULL,","));
printf("6 %s\n",zstring_strtok(NULL,","));
Example Output
1 A
2 B
3 ,
4 ,
5 C
6 (null)
你甚至可以使用while循环(标准库的strtok()
也会得到相同的结果)
char s[]="some text here;
do {
printf("%s\n",zstring_strtok(s," "));
} while(zstring_strtok(NULL," "));
如果你愿意改变原始字符串,你可以简单地用\0
替换分隔符。原始指针将指向第一个字符串,而分隔符后面的指针将指向第二个字符串。好处是你可以在不分配任何新字符串缓冲区的情况下同时使用这两个指针。
你可以做:
char str[] ="Stackoverflow Serverfault";
char piece1[20] = ""
,piece2[20] = "";
char * p;
p = strtok (str," "); // call the strtok with str as 1st arg for the 1st time.
if (p != NULL) // check if we got a token.
{
strcpy(piece1,p); // save the token.
p = strtok (NULL, " "); // subsequent call should have NULL as 1st arg.
if (p != NULL) // check if we got a token.
strcpy(piece2,p); // save the token.
}
printf("%s :: %s\n",piece1,piece2); // prints Stackoverflow :: Serverfault
strtok
调用,直到 strtok
的返回值变成 NULL
。
strtok()
的代码吗? - Naveen