C通过分隔符将字符串拆分为标记并保存为变量

时间:2013-06-13 10:51:03

标签: c

我想将一个字符串拆分为标记并将数据保存到变量中。 我有以下字符串:

John|Doe|Melbourne|6270|AU

我需要按|拆分它,并且每个令牌都保持变量,以便我可以在我的程序中使用它们,例如:

fname = "John"
lname = "Doe"
city = "Melbourne"
zip = "6270"
country = "AU"

到目前为止尝试了这个,我可以访问第一个令牌,其余的我不知道如何(除了一个不帮助我的while循环):

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

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

strtok(str, "|");

printf("%s\n", str);
return 0;
}

5 个答案:

答案 0 :(得分:11)

    char fname[32], lname[32], city[32], zip[32], country[32];

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

    printf("%s\n", fname);
    printf("%s\n", lname);
    printf("%s\n", city);
    printf("%s\n", zip);
    printf("%s\n", country);

答案 1 :(得分:5)

如果格式不变,您可以使用sscanf()

char fname[32], lname[32], city[32], zip[16], country[8];

if(sscanf(str, "%31[^|]|%31[^|]|%31[^|]|%15[^|]%7s",
               fname, lname, city, zip, country) == 5)
{
}

这使用%[]字符集格式说明符来获取“除垂直条之外的所有内容”。包含宽度以防止缓冲区溢出。

答案 2 :(得分:3)

继续打电话给strtok

char* name = strtok(str, "|");
char* surname = strtok(NULL, "|");
...

答案 3 :(得分:3)

strtok返回指向令牌的指针;传递NULL作为检索连续标记的第一个参数:

#define FIELD_LENGTH 20
#define NUM_FIELDS    5
...
char target[NUM_FIELDS][FIELD_LENGTH];
int field = 0;
...
while ( get_next_string( str )) // where get_next_string retrieves your next
{                                // delimited string
  char *token = strtok( str, "|" );
  while ( token )
  {
    strcpy( target[i++], token );
    token = strtok( NULL, "|" );
  }
}

修改

要解决Golgauth的评论,使用strtok时需要记住一些重要事项:

  • 它通过将每个分隔符替换为0来修改输入字符串,这意味着它不能用于字符串文字。如果要保留原始字符串,则必须制作副本以传递给strtok;
  • 它使用一个静态缓冲区来存储它正在修改的字符串,使其不可重入 - 如果多个线程调用strtok来标记不同的字符串,它们将会风互相踩(这被称为竞争条件,程序的行为取决于哪个线程首先访问某些东西)。此外,你不能将调用嵌套到strtok(也就是说,获取一个令牌,然后将其拆分为子字符,然后获取下一个令牌);

在线2011标准提到了更安全(和IINM可重入)替代方案strtok_s,作为附件K(边界检查接口)的一部分;一些实现还提供可重入的strtok_r函数。

答案 4 :(得分:2)

你可以使用sscanf(它可以扫描到达给定分隔符的字符串)

int n; 
char fname[128]= "", lname[128]= "", city[128]= "", zipcode[128]= "", country[128]= "";
n= sscanf str("%127[^|]|%127[^|]|%127[^|]|%127[^|]|%127s", fname, lname, city, zipcode, country); 
if (n==5) {  // five fields scanned

}