2010-06-03 12 views
6

Ich suche ein Zeichen beim ersten Auftreten in der Zeichenkette unter Verwendung des folgenden Codes. Aber es dauert einige Zeit, wenn das Zeichen zu lang ist oder das Zeichen, das ich Suche ist weit entfernt ist, was andere Operationen verzögert. Wie könnte ich dieses Problem angehen? Der Code ist hier unten.Zeichen in der Sprache der Zeichenkette C finden

Hinweis: attrPtr ist eine char *, die einen Verweis auf eine Zeichenfolge enthält, die '"' Zeichen in weitem Umfang enthält.

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); 

Antwort

22

strchr wird in der Regel etwas schneller sein. Außerdem müssen Sie nach dem NUL-Terminator suchen, den strchr für Sie übernimmt.

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'; 

habe ich nicht getestet, aber.

EDIT: Fix-by-One.

+2

+1 Schreibweise NUL richtig. –

+2

'NUL' ist der ASCII-Moniker, der C-Standard verwendet den Begriff 'Nullzeichen'. – dreamlax

+0

@Mathew Vielen Dank für Ihren Vorschlag .... – boom

2

Es wird ein O(n) Algorithmus benötigt, um nach einem Zeichen in der Zeichenfolge zu suchen. Sie können also nicht viel besser machen als das, was Sie bereits tun. Beachten Sie auch, dass Ihnen memset(attrValue, 0, position); fehlt, andernfalls wird Ihre Zeichenfolge attrValue nicht null terminiert.

7

C verfügt über eine integrierte Funktion zum Suchen nach einem Zeichen in einer Zeichenfolge - strchr(). strchr() gibt einen Zeiger auf das gefundene Zeichen zurück, nicht auf die Array-Position. Daher müssen Sie den Zeiger vom zurückgegebenen Zeiger auf den Anfang der Zeichenfolge subtrahieren, um dies zu erhalten. Sie könnten Ihre Funktion wie folgt umschreiben:

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'; 
} 

Dies kann schneller sein als Ihr Original durch einen kleinen konstanten Faktor; Sie werden jedoch keine Beschleunigung der Größenordnung erhalten. Die Suche nach einem Zeichen innerhalb einer ungeordneten Zeichenfolge ist grundsätzlich O (n) in der Länge der Zeichenfolge.

2

Der von Ihnen gepostete Algorithmus behandelt den Fall, in dem das Zeichen nicht in der Zeichenfolge vorhanden ist, nicht ordnungsgemäß. Wenn das passiert, wird es merilly einfach durch den Speicher marschieren, bis es zufällig zufällig ein Byte findet, das zu deinem Char passt, oder du blies an deinem zugewiesenen Speicher vorbei und bekommst einen segfault. Ich vermute, deshalb scheint es manchmal "zu lange dauern".

In C werden Strings normalerweise mit einer 0 beendet (ascii nul oder '\0'). Wenn Sie die Länge der Zeichenfolge im Voraus kennen, können Sie diese alternativ verwenden.

Natürlich gibt es eine Standard-C-Bibliothek-Routine, die genau das tut: strchr(). Ein kluger Programmierer würde das verwenden, anstatt Fehler zu riskieren, indem er seine eigenen rollt.

4

Zwei wichtige Dinge:

1 immer) für eine Nullabschluss überprüfen, wenn eine Zeichenfolge auf diese Weise die Suche:

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

sollte sein:

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

(wenn eine Zeichenfolge übergeben fehlt Ihr gesuchter Charakter, könnte es sehr lange dauern, da es den gesamten Speicher scannt). Edit: Ich habe gerade bemerkt, dass jemand anderes dies vorher gepostet hat, ich, aber naja.Ich stimme nicht zu, btw, strchr() ist in Ordnung, aber eine einfache Schleife, die auch nach dem Terminator sucht, ist in Ordnung (und hat oft auch Vorteile).

2) ACHTUNG von strncpy()!

strncpy(attrValue, attrPtr, position-1); 

strlen (attrPtr)> = (Position-1), so wird dies NICHT null die Zeichenfolge in attrValue beenden, die alle Arten von Problemen, die dazu führen könnten (einschließlich unglaubliche Verlangsamung der Code später). Als Beachtet, ist strncpy() erm, einzigartig gestaltet, so dass, wenn Sie etwas tun, wie:

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

Sie werden 4096 Bytes von Nullen schreiben.

Persönlich verwende ich lstrcpyn() auf Win32, und auf anderen Plattformen habe ich eine einfache Implementierung davon. Es ist viel nützlicher für mich.

Verwandte Themen