[英]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
聲明為具有三個條目,然后使用索引1
到3
對其進行索引。 但是C中的數組具有從0
到size-1
索引(例如,在您的情況下為2
)。
因此,您可以在數組的邊界內寫入/讀取數據,從而導致未定義的行為。
將數組的索引更改為0
到2
,它應該可以正常工作。
在您的代碼中,您有超出索引的問題,導致運行時出現未定義的行為:
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.