2010-06-03 64 views
6

我正在使用以下代碼搜索字符串中第一次出現的字符串。 但是,當角色太長或者我搜索的角色在很遠的範圍內時會花費一些時間,這會延遲其他操作。我怎樣才能解決這個問題。代碼在這裏。查找字符串C語言中的字符

注:attrPtr是一個char *,它在很遠的程度上保存對包含'"'字符的字符串的引用。

int position = 0; 

char qolon = '"';//character to search 

while (*(attrPtr + position++) != qolon); 

char* attrValue = NULL; 

attrValue = (char*)malloc(position * sizeof(char)); 

strncpy(attrValue, attrPtr, position-1); 

回答

22

strchr通常會稍快。另外,你需要檢查一下strchr會爲你處理的NUL終結符。

char *quotPtr = strchr(attrPtr, qolon); 
if(quotPtr == NULL) 
{ 
    ... // Handle error 
} 
int position = quotPtr - attrPtr; 
char* attrValue = (char*) malloc((position + 1) * sizeof(char)); 
memcpy(attrValue, attrPtr, position); 
attrValue[position] = '\0'; 

雖然我還沒有測試過。

編輯:修正了一個。

+2

+1正確拼寫NUL。 – 2010-06-03 04:58:03

+2

'NUL'是ASCII名字對象,C標準使用術語'空字符'。 – dreamlax 2010-06-03 05:30:59

+0

@Mathew感謝您的建議.... – boom 2010-06-03 13:22:49

2

它需要一個O(n)算法來搜索字符串中的字符。所以你不能做比你已經做的更好的事情。此外,請注意,您缺少memset(attrValue, 0, position);,否則您的字符串attrValue將不會以null結尾。

7

C有一個內置函數用於搜索字符串中的字符 - strchr()strchr()返回一個指向找到的字符的指針,而不是數組的位置,所以你必須從返回的指針中減去指向字符串開頭的指針來獲取它。你可以改寫你的功能爲:

char qolon = '"';//character to search 
char *found; 
char *attrVal = NULL; 

found = strchr(attrPtr, qolon); 

if (found) 
{ 
    size_t len = found - attrPtr; 

    attrVal = malloc(len + 1); 
    memcpy(attrVal, attrPtr, len); 
    attrVal[len] = '\0'; 
} 

這可能比你的原始速度快一個小的常數因子;然而,你不會得到一個數量級的加速。在無序字符串中搜索字符基本上是字符串長度的O(n)。

2

您發佈的算法不能正確處理字符不存在於字符串中的情況。如果發生這種情況,它只會在內存中行進,直到它隨機發生一個與你的字符匹配的字節,或者你吹過你分配的內存並獲得段錯誤。我懷疑這就是爲什麼有時候它似乎「花太長時間」。

在C中,字符串通常以0(ascii nul或'\0')結尾。或者,如果您提前知道字符串的長度,則可以使用該字符串。

當然,有一個標準的C庫例程完全是這樣做的:strchr()。一個聰明的程序員可以使用它,而不是通過滾動自己的方式來防範錯誤。

4

兩個重要的事情:

1)經常檢查空終止搜索字符串時這樣說:

while (*(attrPtr + position++) != qolon); 

應該是:

while (attrPtr[position] && attrPtr[position++] != qolon); 

(如果傳遞了一個字符串缺乏您搜索到的字符,它可能需要很長時間才能掃描所有內存)。編輯:我只是注意到有人在之前發佈了這個,但我很好。我不同意,順便說一句,strchr()是好的,但一個簡單的循環,也檢查終結者是好的(通常也有優勢)。

2)注意strncpy()!

strncpy(attrValue, attrPtr, position-1); 

的strlen(attrPtr)> =(位置1),因此這將NOT空終止在attrValue字符串,這可能導致各種問題(包括在代碼難以置信減速以後)。作爲一個相關的說明,函數strncpy()是ERM,設計獨特,所以如果你做這樣的事情:

char buf[512]; 
strncpy(buf,"",4096); 

你會寫4096個字節零的。

就個人而言,我在Win32上使用lstrcpyn(),而在其他平臺上我有一個簡單的實現。這對我來說更有用。