Ist es legal, eine nicht nullterminierte Zeichenfolge an strncmp in C zu übergeben?

Lesezeit: 6 Minuten

Benutzeravatar von Bilow
Bilow

Ich habe ein Array von 16 Bytes, das den Namen des Segments einer ausführbaren Datei enthält.

char segname[16];

Wenn die Länge des Segmentnamens weniger als 16 Bytes beträgt, wird der Rest mit Nullbytes aufgefüllt. Andernfalls gibt es kein abschließendes Null-Byte.

Ich möchte vergleichen segname zu diversen Saiten, zB __text.

Ist es legal anzurufen strncmp mit einer nicht nullterminierten Zeichenfolge?

Dieser Beitrag geht davon aus, dass es legal ist. Dieser Quellcode macht es auch legal. Aber auf meiner Männerseite steht:

Das strncmp() Die Funktion vergleicht lexikografisch die nullterminierten Strings s1 und s2.

Die Größe übergeben strncmp wird die Größe von haben segname.

Ich frage mich, worauf ich mich beziehen soll.

  • Ein char Array, das nicht ist '\0'-terminated ist kein String!

    – zu ehrlich für diese Seite

    1. Januar 2017 um 20:32 Uhr


  • @Olaf Richtig, ich werde es nennen possibly null-terminated array nächstes Mal.

    – Bilow

    1. Januar 2017 um 20:43 Uhr

  • Du hast meinen Punkt verfehlt! Es gibt keinen String-Typ in C. Sie sollten jedoch in Betracht ziehen, diesen zusätzlichen Betrag auszugeben char und beenden Sie immer das Array. Dadurch können andere String-Funktionen verwendet werden. Sicher ist sicher!

    – zu ehrlich für diese Seite

    1. Januar 2017 um 22:53 Uhr

  • Ich bin mir nicht sicher, welche Manpage Sie zitieren. Aber die POSIX-Manpage auf Ubuntu sagt: “Die Funktion strncmp() soll nicht mehr als n Bytes (Bytes, die einem Nullbyte folgen, werden nicht verglichen) von dem Array, auf das s1 zeigt, mit dem Array vergleichen, auf das s2 zeigt.” was sollte klar sein und stammt direkt aus dem C-Standard. Vielleicht möchten Sie Ihre Manpages aktualisieren?

    – zu ehrlich für diese Seite

    1. Januar 2017 um 22:58 Uhr


  • Damit habe ich kein Problem strncmp. Es ist immer gut, die Norm zu lesen, bevor man eine Frage stellt. Oder – wie ich schrieb – um eine korrekte Manpage zur Verfügung zu haben.

    – zu ehrlich für diese Seite

    2. Januar 2017 um 12:12 Uhr

Gemäß dem C99-Standard, Abschnitt 7.21.4.4, §3., ist es legal:

Das strncmp Die Funktion gibt eine ganze Zahl zurück, die größer, gleich oder kleiner als Null ist, entsprechend als die möglicherweise nullterminiert Array, auf das von gezeigt wird s1 größer als, gleich oder kleiner als die ist möglicherweise nullterminiert Array, auf das von gezeigt wird s2.

Beachten Sie jedoch, dass es heißt Reihe von Charakteren. Wenn ein Array von Zeichen nicht nullterminiert ist, ist dies per Definition der Fall nicht ein Faden.

  • C99 wurde ersetzt; C2011 ist der aktuelle C-Standard. Seine Spezifikation für strncmp() in Abschnitt 7.24.4.4 verzichtet zwar auf die Anforderung, dass die zu vergleichenden Arrays nullterminiert sein müssen.

    – Johannes Bollinger

    1. Januar 2017 um 20:59 Uhr


  • Es sollte jedoch beachtet werden, dass das Weglassen einer Anforderung für eine Null-Terminierung keinen Zugriff außerhalb der Grenzen eines der beiden Eingabearrays erlaubt. Der Aufrufer muss sicherstellen, dass das dritte Argument geeignet ist, um zu vermeiden, dass die Funktion die Grenzen eines der beiden Arrays überschreitet. Der Anrufer riskiert, undefiniertes Verhalten hervorzurufen, wenn er dies nicht tut.

    – Johannes Bollinger

    1. Januar 2017 um 21:02 Uhr

  • @JohnBollinger: Wenn der Standard angibt, dass Zeichen nach einem Nullbyte nicht verglichen werden, sollte dies bedeuten, dass sich eine Implementierung so verhält, als würde sie solche Zeichen nicht lesen? Es scheint kaum ungewöhnlich, dass eine Anwendung eine mit Nullen aufgefüllte Zeichenfolge vergleichen muss [which might lack a trailing zero if it precisely fills its buffer] mit einem nullterminierten [whose buffer might be shorter than that of the zero-padded string]und eine solche Garantie wäre erforderlich, um strncmp für diesen Zweck geeignet zu machen.

    – Superkatze

    1. Januar 2017 um 22:45 Uhr


  • Am Anfang des Abschnitts, der erklärt <string.h>sagt der Standard, dass das Argument n gibt die Länge des Arrays an. strncmp benötigt auch keine NULs. Dies impliziert, dass nichts vorher s1 oder s2 und nichts an oder darüber hinaus s1+n oder s2+n wird zugegriffen.

    – giusti

    1. Januar 2017 um 23:21 Uhr

  • Wenn ich darüber nachdenke, muss die Implementierung im schlimmsten Fall auf alle Zeichen von zugreifen s1 im Vergleich. Es vergleicht keine Zeichen mit unterschiedlichen Verzögerungen von ihren Zeigern. Ich bin versucht, das zu sagen, wenn s1 ist nullterminiert und kleiner als s2dann s2 wird nur beim ersten zugegriffen strlen(s1) Figuren. Aber ich bin unsicher.

    – giusti

    1. Januar 2017 um 23:44 Uhr

Benutzeravatar von user2736738
Benutzer2736738

Die Funktion strncmp vergleicht nicht mehr als n Zeichen (Zeichen, die auf ein Nullzeichen folgen, werden nicht verglichen) aus dem Array, auf das s1 zeigt, mit dem Array, auf das s2 zeigt.

Spezifikation 7.24.4.2 sagt das.C11-Standard.

Zeichen, die keinem Nullzeichen folgen, werden nicht verglichen, daher wird ein Zeichenarray oder eine Zeichenkette mit Nullende erwartet.1

Sie können hier auch Nicht-Null-terminierte Zeichen verwenden, aber in diesem Fall müssen wir die Länge angeben, bis zu der wir es überprüfen müssen, was in einigen Fällen nützlich ist.

Korrekturen


[1] Dass Zeichen, die keinem Nullzeichen folgen, nicht verglichen werden, bedeutet das nicht strncmp erwartet nullterminierte Strings. Es bedeutet nur das strncmp braucht einen Sonderfall, um (zum Beispiel) das zu sagen abc\0def… und abc\0xyz… gleich vergleichen. Es ist nichts falsch daran, zwei char-Arrays zu vergleichen, die nicht nullterminiert sind (bis zur angegebenen Länge), oder ein nullterminiertes char-Array mit einem anderen zu vergleichen, das nicht nullterminiert ist

Dies wird direkt aus dem Kommentar von hinzugefügt David Hammen

  • Beachten Sie, dass “… einem NULL-Zeichen folgen …” sinnvoller ist als “… einem Nullzeichen folgen … “. NULL ist der Nullzeiger konstant mit Zeigern verbunden. Speichern Sie die Großbuchstaben NULL zur Diskussion über Zeiger.

    – chux – Wiedereinsetzung von Monica

    1. Januar 2017 um 21:08 Uhr

  • Oder Sie können NUL schreiben, wie es normalerweise in ASCII und von ASCII abgeleiteten Standards bezeichnet wird.

    – giusti

    1. Januar 2017 um 21:10 Uhr

  • @giusti C ist nicht für die Verwendung von ASCII spezifiziert, tut dies jedoch häufig. Deswegen NUL (ein ASCII-definierter Wert) wird in der C-Spezifikation nicht verwendet (außer in einer nicht normativen Fußnote). Eine gute Alternative zu Nullzeichen ist '\0'. Sieh dir das an

    – chux – Wiedereinsetzung von Monica

    1. Januar 2017 um 21:13 Uhr


  • Zeichen, die keinem Nullzeichen folgen, werden nicht verglichen, daher wird ein Zeichenarray oder eine Zeichenkette mit Nullende erwartet“: Diese Antwort ist falsch. Der von Ihnen zitierte Text legt fest, a Beschränkung zum strncmp: Es wird nie über ein Nullzeichen hinaus gelesen, wenn einer anwesend ist. Es verlangt nicht a Erfordernis dass es ein Nullzeichen geben muss. Auch mit strncmp Sie stets müssen Sie die maximale Anzahl von Zeichen angeben, die überprüft werden sollen.

    – giusti

    2. Januar 2017 um 12:42 Uhr


  • In Bezug auf eine Bearbeitung: Beheben Sie dies: Zeichen, die keinem Nullzeichen folgen, werden nicht verglichen, daher wird ein Zeichenarray oder eine Zeichenkette mit Nullende erwartet. Dass Zeichen, die keinem Nullzeichen folgen, nicht verglichen werden, bedeutet das nicht strncmp erwartet nullterminierte Strings. Es bedeutet nur das strncmp braucht einen Sonderfall, um (zum Beispiel) das zu sagen abc\0def... und abc\0xyz... gleich vergleichen. Es ist nichts falsch daran, zwei char-Arrays zu vergleichen, die nicht nullterminiert sind (bis zur angegebenen Länge), oder ein nullterminiertes char-Array mit einem anderen zu vergleichen, das nicht nullterminiert ist.

    – David Hamm

    2. Januar 2017 um 16:54 Uhr

1405550cookie-checkIst es legal, eine nicht nullterminierte Zeichenfolge an strncmp in C zu übergeben?

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

Privacy policy