簡體   English   中英

使用strtok在C中解析字符串

[英]String parsing in C using strtok

我有這個小源代碼,用於測試解析類似於我需要在其他項目中使用的變量string

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


int main (void)
{
    char string[] = "C-AC-2C-3C-BOB";
    char* s;
    char* hand[3];
    char* usr;


    s = (char*) calloc(1, sizeof(char));
    hand[1] = (char*) calloc(3, sizeof(char));
    hand[2] = (char*) calloc(3, sizeof(char));
    hand[3] = (char*) calloc(3, sizeof(char));
    usr = (char*) calloc(21, sizeof(char));

    s = strtok (string,"-");
    hand[1] = strtok (NULL, "-");
    hand[2] = strtok (NULL, "-");
    hand[3] = strtok (NULL, "-");
    usr = strtok (NULL, "\0");

    printf("%s:%s:%s:%s:%s\n", s, hand[1], hand[2], hand[3], usr);

    return 0;
}

問題是我得到了這些3C:AC:2C:3C:BOB是printf而不是C:AC:2C:3C:BOB

- - - -編輯 - - -

沒有內存泄漏的代碼。 問題仍然存在

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


int main (void)
{
    char string[] = "C-AC-2C-3C-BOB";
    char* s;
    char* hand[3];
    char* usr;

    s = strtok (string,"-");
    hand[1] = strtok (NULL, "-");
    hand[2] = strtok (NULL, "-");
    hand[3] = strtok (NULL, "-");
    usr = strtok (NULL, "\0");

    printf("%s:%s:%s:%s:%s\n", s, hand[1], hand[2], hand[3], usr);

    return 0;
}

您將數組hand聲明為具有三個條目,然后使用索引13對其進行索引。 但是C中的數組具有從0size-1索引(例如,在您的情況下為2 )。

因此,您可以在數組的邊界內寫入/讀取數據,從而導致未定義的行為。

將數組的索引更改為02 ,它應該可以正常工作。

在您的代碼中,您有超出索引的問題,導致運行時出現未定義的行為:

hand[3] = strtok (NULL, "-"); 
     ^

printf("%s:%s:%s:%s:%s\n", s, hand[1], hand[2], hand[3], usr);
                                                     ^
                                                 wrong index value   

記住數組中的索引值根據聲明char* hand[3];0開頭char* hand[3]; 索引值可以是0到2

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


int main (void)
{
    char string[] = "C-AC-2C-3C-BOB";
    char* s;
    char* hand[3];
    char* usr;

    s = strtok (string,"-");
    hand[0] = strtok (NULL, "-");
    hand[1] = strtok (NULL, "-");
    hand[2] = strtok (NULL, "-");
    usr = strtok (NULL, "\0");

    printf("%s:%s:%s:%s:%s\n", s, hand[0], hand[1], hand[2], usr);

    return 0;
}

你不需要calloc你的指針,因為strtok()將返回一個有效的內存地址(實際上strtok()修改字符串並用空字符替換分隔符)。 另一個問題是數組的索引:在C中,索引從0開始。 hand的第一個元素是hand[0] ,最后一個是hand[2]

這是你的程序堆棧:

+-----------------------+
|       ...
|
|0x***00 hand[0]
|
|
|           
|0x***04 hand[1]       
|
|
|     
|0x***08 hand[2]           
|                  
|
|
|0x***0C hand[3]    
|                       <---hander[1] pointer this address    
|    
|______  hand[3] end here 

所以手[3]使用地址覆蓋*手[1],這是3C來的

首先,您應該注釋這些行以避免內存泄漏:

s = (char*) calloc(1, sizeof(char));
hand[1] = (char*) calloc(3, sizeof(char));
hand[2] = (char*) calloc(3, sizeof(char));
hand[3] = (char*) calloc(3, sizeof(char));
usr = (char*) calloc(21, sizeof(char));

然后,在更改代碼后,我在Windows和Linux中構建並運行結果,既沒有得到意外的打印結果。

暫無
暫無

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

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