C strtok()将字符串拆分为标记但保持旧数据不变

bst*_*teo 4 c

我有以下代码:

#include <stdio.h>
#include <string.h>

int main (void) {
char str[] = "John|Doe|Melbourne|6270|AU";

char fname[32], lname[32], city[32], zip[32], country[32];
char *oldstr = str;

    strcpy(fname, strtok(str, "|"));
    strcpy(lname, strtok(NULL, "|"));
    strcpy(city, strtok(NULL, "|"));
    strcpy(zip, strtok(NULL, "|"));
    strcpy(country, strtok(NULL, "|"));

    printf("Firstname: %s\n", fname);
    printf("Lastname: %s\n", lname);
    printf("City: %s\n", city);
    printf("Zip: %s\n", zip);
    printf("Country: %s\n", country);
    printf("STR: %s\n", str);
    printf("OLDSTR: %s\n", oldstr);

return 0;
}
Run Code Online (Sandbox Code Playgroud)

执行输出:

$ ./str
Firstname: John
Lastname: Doe
City: Melbourne
Zip: 6270
Country: AU
STR: John
OLDSTR: John
Run Code Online (Sandbox Code Playgroud)

为什么我不能保留旧数据,也不能保留,str或者oldstr我做错了什么,我怎么能不改变数据或保留数据呢?

Gri*_*han 22

当你执行strtok(NULL, "|")strtock查找令牌并将null放在原位(替换令牌\0)并修改字符串.

str,成为:

char str[] = John0Doe0Melbourne062700AU;

  Str array in memory 
+------------------------------------------------------------------------------------------------+
|'J'|'o'|'h'|'n'|0|'D'|'o'|'e'|0|'M'|'e'|'l'|'b'|'o'|'u'|'r'|'n'|'e'|0|'6'|'2'|'7'|'0'|0|'A'|'U'|0|
+------------------------------------------------------------------------------------------------+
                 ^  replace | with \0  (ASCII value is 0)
Run Code Online (Sandbox Code Playgroud)

考虑图表是重要的,因为char '0'0是不同的(在字符串6270中的字符是char括号,'其中\00表示为数字)

当您打印使用str的%s它打印字符高达首先\0John

为了保持原始str不变,你应该将str复制到某个tempstr变量中,然后tempstrstrtok()以下字符串中使用该字符串:

char str[] = "John|Doe|Melbourne|6270|AU";
char* tempstr = calloc(strlen(str)+1, sizeof(char));
strcpy(tempstr, str);
Run Code Online (Sandbox Code Playgroud)

现在tempstr在代码中使用此字符串代替str.

  • 您可以用简单的“strdup”替换“calloc + strcpy”。 (2认同)