簡體   English   中英

使用 strtok 在 c 中拆分字符串

[英]Using strtok to split a string in c

在下面的代碼中,我嘗試拆分字符串以從字符串中獲取由“,”分隔的名稱。

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


int main(void)
{
    char *st = "Addison,Jayden,Sofia,Michael,Andrew,Lily,Benjamin";
    char *name[7];
    char *separate = ",";

    char *token = strtok(st, separate);
    int i = 0;
    while(token != NULL)
    {
        strcpy(name[i], token);
        token = strtok(NULL, ",");
        i++;
    }
    for (int j = 0; j < 7; j++)
    {
        printf("%s\n", name[j]);
    }
}

但是,當我嘗試運行代碼時遇到了分段錯誤。 我嘗試調試它,似乎這行特定的代碼是錯誤的來源:

char *token = strtok(st, separate);

誰能告訴我我做錯了什么?

您聲明了一個指向字符串文字的指針

char *st = "Addison,Jayden,Sofia,Michael,Andrew,Lily,Benjamin";

您不能更改字符串文字。 任何改變字符串文字的嘗試都會導致未定義的行為。

來自 C 標准(6.4.5 字符串文字)

7 如果這些數組的元素具有適當的值,則未指定這些數組是否不同。 如果程序嘗試修改這樣的數組,則行為未定義

另一方面,標准 C 函數strtok更改傳遞給它的字符串。

來自 C 標准(7.23.5.8 strtok 函數)

4 strtok 函數然后從那里搜索包含在當前分隔符字符串中的字符。 如果沒有找到這樣的字符,則當前標記會延伸到 s1 指向的字符串的末尾,后續對標記的搜索將返回空指針。 如果找到這樣的字符,它會被一個空字符覆蓋,終止當前標記。 strtok 函數保存指向下一個字符的指針,下一次搜索標記將從該字符開始。

所以將聲明替換為

char st[] = "Addison,Jayden,Sofia,Michael,Andrew,Lily,Benjamin";

您還聲明了一個未初始化的指針數組。

char *name[7];

所以這個說法

strcpy(name[i], token);

還調用未定義的行為。

相反,你可以寫

name[i] = token;

由於變量 i 包含 tfokens 的數量,因此通常這個循環

for (int j = 0; j < 7; j++)
{
    printf("%s\n", name[j]);
}

應該至少像(不使用幻數 7)那樣重寫

for (int j = 0; j < i; j++)
{
    puts( name[j] );
}

但是,當我嘗試運行代碼時遇到了分段錯誤

兩個問題:

  • 試圖更改不可編輯的字符串。
  • 嘗試訪問不屬於進程的位置。

其中任何一個都可能導致崩潰。 (段錯誤)

內存分配問題
聲明:

  char *name[7];

創建一個包含 7 個指針的數組。 它們中的每一個都需要分配內存才能以這種方式使用:

strcpy(name[i], token);

內存分配示例:

for(int i=0;i<7;i++)
{
    name[i] = malloc((maxNameLen+1)*sizeof(name[i]));
    if(!name[i]) 
    {
        //handle error
    }
}
//now each pointer has space for up to maxNameLen+1 characters

不可編輯的字符串

char *st = "Addison,Jayden,Sofia,Michael,Andrew,Lily,Benjamin";

要編輯的字符串不能采用這種形式(即字符串文字)。 它必須是可編輯的形式,以便strtok()更改它,就像解析時一樣。 有許多可編輯的字符串形式,以下是兩個示例:

//Create an editable form:
char st[] = {"Addison,Jayden,Sofia,Michael,Andrew,Lily,Benjamin"};

//Create an editable copy of original: (requires freeing when done using)
char *duplicate = strdup(st);
if(duplicate)
{
    //success duplicating, now parse duplicate.

這里還有另一個討論解釋了 C 中的可編輯/不可編輯字符串。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM