strncmp richtige Verwendung
Hier der kurze hintergrund: ich habe ein client-und ein server-Programm, dass die Kommunikation mit jedem anderen über einen Unix-socket. Beim Parsen der empfangenen Nachrichten auf der server-Seite bin ich versucht, strncmp, um herauszufinden, was zu tun ist.
Das problem das ich habe, ist, herauszufinden, was genau für die Länge-argument von strncmp. Der Grund dafür ist, problematisch ist, dass einige meiner Nachrichten, die ein gemeinsames Präfix. Ich habe zum Beispiel eine Nachricht "getPrimary", die bewirkt, dass der server antwortet mit einem primär-server-Adresse und eine Nachricht "getPrimaryStatus", die bewirkt, dass der server antwortet mit dem status der primären server. Mein Erster Gedanke war, das folgende zu tun:
if(strncmp(message,"getPrimary",strlen("getPrimary"))==0){
return foo;
}
else if(strncmp(message,"getPrimaryStatus",strlen("getPrimaryStatus"))==0){
return bar;
}
Das problem mit diesem ist, wenn ich den server "getPrimaryStatus", der code wird immer return foo, weil strncmp ist die Prüfung nicht weit genug in der Zeichenfolge. Ich könnte passieren in strlen(message) als length-argument, strncmp, aber dies scheint die Niederlage der Zweck der Verwendung strncmp, zu verhindern, dass überlauf im Falle von unerwarteten Eingang. Ich habe eine statische variable für die maximale Länge der Nachricht kann ich Lesen, aber es scheint, wie an das in als die Länge ist nur sicher, wenn die Nachricht überläufe, die Auswirkungen minimiert werden.
Habe ich ein paar Lösungen, aber Sie sind nicht sehr hübsch, so dass ich Frage mich, ob es einen gemeinsamen Weg des Umgangs mit diesem problem.
Referenz, meine aktuellen Lösungen:
Um meine if /else if-Anweisungen in einer Weise, dass, dass alle Nachrichten mit gemeinsamen Präfixen sind geprüft, in der Reihenfolge absteigender Länge (das scheint wie ein wirklich guter Weg, um zu werfen eine landmine in meinem code für jeden, der versucht, etwas hinzufügen, um es später auf).
Gruppe meine Nachrichten mit gemeinsamen Präfixen zusammen und nach dem suffix der ersten:
if(strncmp(message,"getPrimary",strlen("getPrimary"))==0){
if(strncmp(message,"getPrimaryStatus",strlen("getPrimaryStatus"))==0){
return bar;
else
return foo;
}
}
Aber das fühlt sich einfach chaotisch, vor allem, da ich über 20 verschiedene mögliche Nachrichten, die ich bin-handling.
Erstellen Sie ein array von allen möglichen Nachrichten, die ich haben, fügen Sie eine Funktion hinzu, um meine init-Sequenz, um das array in absteigender Länge, und habe auch meine code-Suche durch die Elemente der Liste, bis es eine übereinstimmung findet. Dies scheint kompliziert und albern.
Wie es scheint, dies sollte eine gemeinsame genug Thema, dass es sollte eine Lösung sein, für die es irgendwo, aber ich habe nicht in der Lage gewesen, irgendetwas zu finden, so weit.
Vielen Dank im Voraus für die Hilfe!
InformationsquelleAutor Jordan Wills | 2010-12-03
Du musst angemeldet sein, um einen Kommentar abzugeben.
Vorausgesetzt, dass die Zeichenfolge in
message
ist soll zu null-terminiert sein, der einzige Grund für die Verwendungstrncmp()
hier eher alsstrcmp()
wäre, um zu verhindern, dass es auf der Suche nach dem Endemessage
, in dem Fall, womessage
ist nicht null-terminiert ist.Als solche, die
n
Sie anstrncmp()
sollte die empfangene Größemessage
, die Sie wissen sollten (von den Rückgabewert derread()
/recv()
Funktion, die die Nachricht gelesen haben).Ich glaube, dass man die Größe der Nachricht zu strncmp stattdessen ist eine unvollständige Lösung für Ihr problem. Bitte siehe meine Lösung für die details.
Vergleiche zwischen strings mit vielen passenden Zeichen können die meisten effizient durchgeführt unter Verwendung eines "chunking" - Ansatz, während die Vergleiche zwischen Zeichenketten, die sich frühzeitig auf möglicherweise effizienter Verwendung eines Zeichens-at-a-time-Ansatz. Ich wäre nicht überrascht, wenn einige Implementierungen von strncmp verwenden, chunking, wenn "n" ist groß, aber es wäre besser, wenn gab es separate Funktionen für die Anwendungsfälle, bei denen die matching ist wahrscheinlich im Vergleich zu jenen, wo es unwahrscheinlich ist.
InformationsquelleAutor caf
Eine Technik ist zu vergleichen mit den längsten Namen Erster Ordnung der Prüfungen (bzw. die Tabelle mit den Schlüsselwörtern), so dass die längeren Namen vor den kürzeren. Jedoch, die Einnahme Ihrer Beispiel:
Werden Sie wahrscheinlich wollen, um sicherzustellen, dass
GetPrimaryIgnition
wird nicht erkannt, alsGetPrimary
. So dass Sie wirklich brauchen, zu vergleichen mit der Länge des längeren der beiden strings - die Nachricht oder das Schlüsselwort.Ihre Daten-Struktur, die hier sein könnten:
Können Sie dann eine Schleife durch diese Tabelle finden Sie den entsprechenden Befehl. Mit etwas Vorsicht begrenzen Sie den Bereich, den Sie haben, zu betrachten. Beachten Sie, dass die
sizeof()
Werte sind NULL am Ende der Zeichenfolge. Dies ist nützlich, wenn Sie null beenden Ihre NachrichtJedoch, es ist die mit Abstand einfachste, wenn Sie null beenden Sie den Befehl Wort in der Nachricht, entweder durch kopieren der Nachricht irgendwo, oder indem Sie die Nachricht in situ. Sie verwenden dann
strcmp()
stattstrncmp()
. Einen Kürzesten Eindeutigen Präfix-Suche schwieriger code.Einen plausiblen Weg zu finden, den Befehl Wort mit
strcspn()
- vorausgesetzt, Ihre Befehle sind alle alphabetisch oder alphanumerisch.InformationsquelleAutor Jonathan Leffler
Ich habe das Gefühl, dass Sie mit strncmp, um Pufferüberlauf zu verhindern, aber die Botschaft ist bereits in den Speicher kopiert (d.h. die message-Puffer). Auch der Prototyp
zeigt an, dass die Funktion hat keine Nebenwirkungen (D. H. Sie ändern sich nicht, entweder input-buffer), damit sollte es keine Gefahr, dass Sie überschrieben werden, die die Puffer-und change memory. (Dies ist nicht der Fall für strcpy(). )
Könnte man sicherstellen, dass die Länge Ihrer Nachricht Puffer länger ist als die längsten Befehls-string. Auf diese Weise sind Sie sicher, dass Sie immer Zugriff auf den Speicher, die Sie besitzen.
Auch, wenn Sie darauf bestehen, mit strncmp Sie speichern könnte Ihre Liste der Befehle in ein array und Sortiere es vom größten zum kleinsten. Man könnte assoziieren Sie jede Zeichenfolge mit einer Länge (und evtl. einen Funktionszeiger ausführen einer Prozedur).
Schließlich konnte man eine C-version von dem, was C++ fordert eine Karte oder was Ruby oder PHP-Aufruf assoziative arrays. Dies ermöglicht die Bibliothek Griff diese if-else-Baum für Sie effizient und korrekt.
InformationsquelleAutor Commodore63
Graben aus meinem Gedächtnis zu tun C-Programmierung vor einem Jahr, ich denke, das Dritte argument soll sagen, die Funktion, wie viele Zeichen für den Vergleich. Deshalb ist es sicher wie Sie Steuern, wie viele Zeichen verarbeiten
Also sollte so etwas wie:
InformationsquelleAutor Andreas Wong
Nicht verwenden
strncmp()
. Verwendenstrlcmp()
statt. Es ist sicherer.InformationsquelleAutor Paul Schreiber
Kommt Ihre Nachricht enthält nur einen dieser Befehle, oder ein command-string gefolgt von Leerzeichen/open-Klammer/etc.?
Wenn es ersteres ist, fallen
strncmp
und verwenden nurstrcmp
.Falls letzteres zutrifft, kreuzen Sie einfach
isspace(message[strlen(command)])
odermessage[strlen(command)]=='('
oder ähnliches. (Hinweis:strlen(command)
ist eine Konstante, und Sie sollten wahrscheinlich schreiben Sie es als solches, oder ein makro verwenden, um die Größe des string-literal.)sizeof("KeyWord")-1
- weilsizeof()
zählt das terminal null zu. Es ist eine compile-Zeit-Konstante, natürlich.Ja, ich glaube, ich sollte erwähnt haben, dass alle.
InformationsquelleAutor R..
Der einzige sichere Weg, um strncmp, um zu bestimmen, ob zwei strings gleich sind, ist zu überprüfen, im Voraus, dass die strings die gleiche Länge haben:
Sonst werden Sie match etwas länger oder kürzer als Ihre Vergleich:
strncmp(a, "test", strlen("test"))
Spiele "testen", "testen und eine ganze Reihe von anderen Zeichen", ect.strncmp(a, "test", strlen(a))
entspricht,"", "t", "te", "tes".InformationsquelleAutor Will Brode
Verwenden strcmp, aber auch vergleichen Sie die Längen der beiden strings. Wenn die Längen identisch sind, dann strcmp geben Sie das Ergebnis Sie suchen.
InformationsquelleAutor captain obvious