Was ist der Unterschied zwischen memcmp, strcmp und strncmp in C?

Lesezeit: 7 Minuten

Benutzeravatar von und3rd06012
und3rd06012

Ich habe dieses kleine Stück Code zum Testen in C geschrieben memcmp() strncmp() strcmp() Funktionen in C.

Hier ist der Code, den ich geschrieben habe:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
        char *word1="apple",*word2="atoms";

        if (strncmp(word1,word2,5)==0)
                printf("strncmp result.\n");
        if (memcmp(word1,word2,5)==0)
                printf("memcmp result.\n");
        if (strcmp(word1,word2)==0)
                printf("strcmp result.\n");
}

Kann mir jemand die Unterschiede erklären, weil ich mit diesen drei Funktionen verwirrt bin?

Mein Hauptproblem ist, dass ich eine Datei habe, in der ich ihre Zeile tokenisiere. Das Problem ist, dass ich den Tokenisierungsprozess stoppen muss, wenn ich das Wort “Atome” in der Datei tokenisiere.

Ich habe es zuerst versucht strcmp() aber als es den Punkt erreichte, an dem das Wort “Atome” in die Datei eingefügt wurde, hörte es leider nicht auf und fuhr fort, aber als ich eines der beiden verwendete memcmp() oder der strncmp() es hörte auf und ich war glücklich.

Aber dann dachte ich, was wäre, wenn es einen Fall geben würde, in dem es eine Zeichenfolge gibt, in der die ersten 5 Buchstaben a, t, o, m, s sind und diesen weitere Buchstaben folgen.

Leider waren meine Gedanken richtig, als ich es mit dem obigen Code durch Initialisierung getestet habe word1 zu “atomsaaaaa” und word2 zu Atomen und memcmp() und strncmp() in den if-Anweisungen wurde 0 zurückgegeben. Auf der anderen Seite strcmp() es tat es nicht. Es scheint, dass ich verwenden muss strcmp().

  • Kudos für die Einbeziehung des Quellcodes. Nun, es würde Ihre Frage klarer machen, wenn Sie zeigen würden, welche Ergebnisse Sie erhalten und welche Ergebnisse Sie erwartet haben.

    – Pascal Cuoq

    26. Oktober 2012 um 23:00 Uhr


  • @PascalCuoq zum Beispiel, wenn ich word1 auf “atomr” und word2 auf “atoms” initialisiere, ist die if-Anweisung, die memcmp() enthält, nie wahr, wenn ich die ausführbare Datei ausführe.

    – und3rd06012

    26. Oktober 2012 um 23:22 Uhr

  • @PascalCuoq.Okay, ich habe meine Antwort auf die Frage gefunden.

    – und3rd06012

    27. Oktober 2012 um 0:02 Uhr

  • @el10780: Nein, ich meinte eine Handbuchseite. Zum Beispiel so – Kernel.org/doc/man-pages/online/pages/man3/memcmp.3.html

    Benutzer405725

    27. Oktober 2012 um 0:04 Uhr

  • Es ist erwähnenswert, dass memcmp viel schneller sein kann, da es normalerweise so optimiert ist, dass es den größten Typ verwendet, der von einem einzelnen Lade- und Speichervorgang unterstützt wird, sobald eine der Adressen ausgerichtet ist. Es werden also tatsächlich viele Zeichen auf einmal verglichen, möglicherweise 8 Zeichenvergleiche, wahrscheinlich mindestens 4.

    – 2013 Asker

    28. Dezember 2013 um 0:45 Uhr

Zusamenfassend:

  • strcmp vergleicht nullterminierte C-Strings
  • strncmp vergleicht höchstens N Zeichen von nullterminierten C-Strings
  • memcmp vergleicht binäre Bytepuffer von N Bytes

Also, wenn Sie diese Zeichenfolgen haben:

const char s1[] = "atoms\0\0\0\0";  // extra null bytes at end
const char s2[] = "atoms\0abc";     // embedded null byte
const char s3[] = "atomsaaa";

Dann gelten diese Ergebnisse:

strcmp(s1, s2) == 0      // strcmp stops at null terminator
strcmp(s1, s3) != 0      // Strings are different
strncmp(s1, s3, 5) == 0  // First 5 characters of strings are the same
memcmp(s1, s3, 5) == 0   // First 5 bytes are the same
strncmp(s1, s2, 8) == 0  // Strings are the same up through the null terminator
memcmp(s1, s2, 8) != 0   // First 8 bytes are different

  • Danke Adam. Ihre Antwort verdeutlicht die Verwendung dieser drei Funktionen sehr.

    – und3rd06012

    27. Oktober 2012 um 0:26 Uhr

  • bedeutet, dass memcmp strcmp ähnlich ist, außer dass Bytes gleich 0 nicht als Vergleichsterminatoren behandelt werden. Daher verwendet strcmp im Grunde die Eigenschaften von Zeichenfolgen, die mit einem Nullzeichen enden.

    – Sarwan

    24. November 2014 um 12:29 Uhr


  • Gute Antwort. Ich habe gerade ein paar Stunden damit verbracht, herauszufinden, warum der Vergleich von 2 24-Byte-Strings (nicht nullterminiert) in etwa 50% der Fälle 0 zurückgibt und den Rest der Zeit einen zufälligen Wert zurückgibt. memcmp war definitiv das, was ich hätte verwenden sollen.

    – mref555

    5. März 2020 um 14:05 Uhr

memcmp vergleicht eine Anzahl von Bytes.
strcmp und dergleichen vergleichen Saiten.

Sie schummeln in Ihrem Beispiel, weil Sie wissen, dass beide Zeichenfolgen 5 Zeichen lang sind (plus das Null-Terminator). Was aber, wenn Sie die Länge der Saiten nicht kennen, was oft der Fall ist? Nun, Sie verwenden strcmp Weil es weiß, wie man mit Strings umgeht, memcmp nicht.

memcmp dreht sich alles um den Vergleich von Byte-Sequenzen. Wenn Sie wissen, wie lang jede Saite ist, könnten Sie sie verwenden memcmp vergleichen, aber wie oft ist das der Fall? Selten. Sie benötigen häufig Zeichenfolgenvergleichsfunktionen, weil sie wissen, was eine Zeichenfolge ist und wie sie zu vergleichen sind.

Alle anderen Probleme, die Sie haben, sind aus Ihrer Frage und Ihrem Code unklar. Seien Sie jedoch versichert strcmp ist im allgemeinen Fall für String-Vergleiche besser gerüstet als memcmp ist.

  • Lassen Sie mich anders fragen. Was passiert, wenn ich memcmp verwende und Wort1 mit “atomr” und Wort2 mit “atoms” initialisiere? Wird es 0 zurückgeben oder nicht?

    – und3rd06012

    26. Oktober 2012 um 23:37 Uhr

  • @el10780: Das hängt davon ab, welche Länge Sie ihm übergeben. Wenn du fragst memcmp um 4 oder weniger Bytes zu vergleichen, wird 0 (gleich) zurückgegeben; Wenn Sie es auffordern, 5 oder mehr Bytes zu vergleichen, wird es nicht 0 (ungleich) zurückgeben.

    – Adam Rosenfield

    26. Oktober 2012 um 23:41 Uhr

  • Verzeihen Sie meine Unwissenheit, aber ich konnte den Unterschied zwischen “atoms” und “atomr” in Bezug auf die Byte-Sequenz nicht verstehen. Sie haben die gleiche Größe, oder? Aber die Byte-Sequenz für “atomr” ist 97.116.111.109.114 und für “atoms ” ist 97.116.111.109.115. Wenn also memcmp alle fünf Zeichen überprüft, wird nicht 0 zurückgegeben. Trotzdem danke für Ihre schnellen Antworten und Ihre Hilfe.

    – und3rd06012

    26. Oktober 2012 um 23:49 Uhr


Benutzeravatar von Arvind kr
Arvind kr

strcmp():

  • Es wird verwendet, um die beiden in zwei Variablen gespeicherten Zeichenfolgen zu vergleichen. Der Vergleich dauert einige Zeit. Und so verlangsamt es den Prozess.

strncmp():

  • Es ist dem vorherigen sehr ähnlich, aber in diesem vergleicht es nur die ersten n Zeichen. Auch das verlangsamt den Prozess.

memcmp():

  • Diese Funktion wird verwendet, um zwei Variablen anhand ihres Speichers zu vergleichen. Es vergleicht sie nicht einzeln, es vergleicht vier Zeichen gleichzeitig. Wenn Ihr Programm zu sehr auf Geschwindigkeit bedacht ist, empfehle ich die Verwendung von memcmp().

  • -1, weil dies falsch ist und eine Menge unbegründeter Annahmen bezüglich der Geschwindigkeit und Implementierung dieser Funktionen trifft. (z. B. Geschwindigkeit von strcmp und strncmp) (z. B. Implementierung von memcmp, die Wörter gleichzeitig liest). Beantwortet die Frage überhaupt nicht richtig.

    – Wiz

    28. Januar 2015 um 23:05 Uhr

  • Im Gegensatz zum Argument von Wiz ist Arvid der einzige, der die massiven Geschwindigkeitsvorteile von memcmp gegenüber strncmp erklärt hat. Er erwähnte nur keine Ausrichtungsoptimierungen. memcmp vergleicht in den meisten Compilern Wörter, nicht Zeichen. Es kann also über die Zeichenfolge hinausschießen, was zu Valgrind-Warnungen führt. Sie müssen den Unterschied zwischen Puffern und Zeichenfolgen nicht wirklich erklären.

    – ländlich

    21. Juni 2016 um 7:55 Uhr

  • Es ist lächerlich zu argumentieren, dass der Unterschied so ist. Der einzige Unterschied bei modernen libcs ​​zwischen memcmp und strcmp besteht darin, dass strcmp prüfen muss, ob es anhalten muss, was etwas mehr Zeit in Anspruch nimmt, als nur Bytes zu vergleichen. Ich habe dies persönlich bewertet und nur einen Geschwindigkeitsunterschied von ~ 10% zwischen memcmp und strcmp gemessen

    – Gabriel Ravier

    31. Januar 2021 um 10:07 Uhr


  • @GabrielRavier Wenn Sie viele Vergleiche anstellen müssen und die Größe der Saiten kennen, sind 10% nicht so minimal, wenn Sie mich fragen

    – Tachi

    11. Mai um 16:15 Uhr

  • @Tachi Das Problem ist, dass die Formulierung des Beitrags extrem schlampig ist und sehr falsche Hinweise auf die beste zu verwendende Methode gibt. Ihr Rat ist gültig, aber die Antwort impliziert dies memcmp hat eine Art massiven Geschwindigkeitsbonus gegenüber strncmpund 10% sind das nicht

    – Gabriel Ravier

    11. Mai um 23:02 Uhr


strncmp und memcmp sind gleich, außer der Tatsache, dass sich ersteres um NULL-terminierte Zeichenfolgen kümmert.

Für strcmp möchten Sie nur das vergleichen, was Sie als Zeichenfolgen kennen, aber manchmal ist dies nicht immer der Fall, z. B. beim Lesen von Zeilen von Binärdateien, und deshalb möchten Sie memcmp verwenden, um bestimmte Eingabezeilen zu vergleichen, die enthalten NUL-Zeichen, aber übereinstimmend, und Sie möchten möglicherweise weitere Längen der Eingabe überprüfen.

Chads Benutzeravatar
Tschad

Zusammenfassen:

  • strncmp() und strcmp() behandeln ein 0-Byte als Ende eines Strings und vergleichen nicht darüber hinaus

  • für memcmp() hat ein 0-Byte keine besondere Bedeutung

1411650cookie-checkWas ist der Unterschied zwischen memcmp, strcmp und strncmp in C?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy