C語言中通過分隔符來擷取字串
最近在工作中要實現這樣一個功能:
從一個文字檔案中按行讀取資料,一行資料中每一列都可能含有空格,所以你要把空格給截取出來。列之間是通過TAB鍵分割的。
我在一開始使用了C的庫函式strtok這個函式。
先介紹一下strtok這個函式原型:
char *strtok(char *src, char *flag)
引數一是你要擷取的字串,引數2是字串中的分隔符。
看一下linux的man手冊是如何結束這個函式的功能的:
這個函式的作用是從字串中提取出分隔符號。
也就說一個字串如果是用/t作為分隔符的話,你使用這個函式後得到的是一個去掉了/t的字串,返回了這個字串的首地址。
在字串中原分隔符的位置,使用/0替換了原來的分隔符。所以你在使用的時候要注意了,如果你的目標字串包含了多個分隔符,你應該這樣使用這個函式:
char *tmp="abc123ABC"; //分隔符是/t
char *p=strtok(tmp,"/t"); //p指向了abc
char *p1=strtok(NULL, "/t"); //p1指向了123
char *p2=strtok(NULL, "/t"); //p2指向了ABC
但是如果你遇到了這樣的情況,那麼這個函式就不會起作用了:
char *tmp="abcABC"; //分隔符是/t,注意第二個是空格
char *p=strtok(tmp,"/t"); //p指向了abc
char *p1=strtok(NULL, "/t"); //p1指向了ABC,不會取出你想要的空格
char *p2=strtok(NULL, "/t"); //p2會報錯的
還有就是這個函式不是執行緒安全的,Linux推薦使用函式strtok_r函式。
顯然這個函式沒有辦法實現我要的功能的,於是我就自己寫了一個函式來實現這個功能:
我的函式如下:
void myStrtok(char *tmp, char flag, char **p1, char **p2, char **p3)
{
//三個二級指標必須要在呼叫函式中定義,這樣在這個函式內的賦值才能傳出去。
int i,j;
int a[3]; //這個地方有一個不好的地方就是這個陣列的定義隨著截取出串的多少你需要改動,最好是自己傳入一個數組,這樣就好了
char *ptr=tmp;
while(*tmp)
{
if(*tmp==flag)
{
a[j++]=i; //記錄分割符出現的位置
*tmp='/0';//把原來的分割符替換為'/0'
}
tmp++;
i++;
}
*p1=ptr;
*p2=ptr+a[0]+1;
*p3=ptr+a[1]+1;
}
在函式外部,你可以定義三個一級指標,如 char *p1, char *p2, char *p3,
這樣就可以使用了上面的函數了:
myStrtok(tmp, '/t', &p1, &p2, &p3);
這樣的話,你就可以擷取到每一個被分隔符分割的字串了,包括空格.