Warum sollte strtok() veraltet sein?

Lesezeit: 4 Minuten

Benutzeravatar von Pushan Gupta
Pushan Gupta

Ich höre dies von vielen Programmierern, dass die Verwendung von strtok in naher Zukunft möglicherweise veraltet ist. Einige sagen, es ist immer noch. Warum ist es eine schlechte Wahl? strtok() eignet sich hervorragend zum Tokenisieren einer bestimmten Zeichenfolge. Hat es etwas mit der zeitlichen und räumlichen Komplexität zu tun? Der beste Link, den ich im Internet gefunden habe, war Dies. Aber das scheint meine Neugier nicht zu lösen. Schlagen Sie nach Möglichkeit Alternativen vor.

  • Zumindest mein eigenes Argument ist, dass es irreführend destruktiv ist. Es modifiziert die Quellzeichenfolge, was man beim Tokenisieren im Allgemeinen nicht tun möchte.

    – Wertigkeit

    2. Juni 2017 um 20:20 Uhr

  • Nachdem ich mich mit der Verwendung von regcomp und regexec vertraut gemacht hatte, fand ich die Verwendung von regex(3) viel nützlicher und leistungsfähiger.

    – Todesgriff

    2. Juni 2017 um 20:24 Uhr

  • Mögliches Duplikat von Warum wird strtok() als unsicher angesehen?

    – phuklv

    3. Juni 2017 um 3:40 Uhr

Benutzeravatar von Eric Lippert
Erich Lippert

Warum ist es eine schlechte Wahl?

Die grundlegende Technik zum Lösen von Problemen durch Programmieren ist das Konstruieren Abstraktionen die verwendet werden können zuverlässig um Teilprobleme zu lösen, und dann komponieren Lösungen für diese Teilprobleme in Lösungen für größere Probleme umzuwandeln.

Das Verhalten von strtok arbeitet auf verschiedene Weise direkt gegen diese Ziele; es ist eine schlechte Abstraktion, die unzuverlässig ist, weil sie schlecht komponiert.

Das grundlegende Problem der Tokenisierung ist: Bei gegebener Position in einer Zeichenfolge geben Sie die Position des Endes des Tokens an, das an dieser Position beginnt. Wenn strtok nur das tun würde, wäre es großartig. Es hätte eine klare Abstraktion, es würde sich nicht auf einen verborgenen globalen Zustand verlassen, es würde seine Eingaben nicht modifizieren.

Um die Einschränkungen von strtok zu sehen, stellen Sie sich vor, Sie versuchen, eine Sprache zu tokenisieren, in der wir Token durch Leerzeichen trennen möchten, es sei denn, das Token ist eingeschlossen " ", in diesem Fall möchten wir eine andere Tokenisierungsregel auf den Inhalt des zitierten Bereichs anwenden und dann mit der Leerzeichentrennungsregel danach weitermachen. strtok komponiert sehr schlecht mit sich selbst und ist daher nur für die trivialsten Tokenisierungsaufgaben nützlich.

Hat es etwas mit der zeitlichen und räumlichen Komplexität zu tun?

Nein.

Schlagen Sie nach Möglichkeit Alternativen vor.

Lexer sind nicht schwer zu schreiben; schreib doch einfach eins!

Bonuspunkte, wenn Sie eine schreiben unveränderlicher Lexer. Ein unveränderlicher Lexer ist eine kleine Struktur, die einen Verweis auf die zu lexende Zeichenfolge, die aktuelle Position des Lexers und jeden vom Lexer benötigten Zustand enthält. Um ein Token zu extrahieren, rufen Sie eine “Next Token”-Methode auf, übergeben den Lexer und erhalten das Token zurück und ein neuer Lexer. Der neue Lexer kann dann zum Lexieren der verwendet werden nächste Token, und Sie verwerfen den vorherigen Lexer, wenn Sie möchten.

Über die unveränderliche Lexer-Technik lässt sich leichter argumentieren als über Lexer, die den Zustand modifizieren. Und Sie können sie debuggen, indem Sie die verworfenen Lexer in einer Liste speichern, und jetzt haben Sie die vollständige Historie der Tokenisierungsoperationen sofort zur Einsicht offen.

  • So habe ich Lexer noch nie gesehen. Danke, dass du das angesprochen hast

    – Pushan Gupta

    2. Juni 2017 um 20:37 Uhr

  • “es würde seine Eingaben nicht ändern” … was in einigen üblichen Situationen eigentlich ungültig ist; zum Beispiel, strtok("hello world", " ") ist eindeutig falsch für einen erfahrenen C-Programmierer, aber für einen Anfänger scheint das alles in Ordnung zu sein! Nichtsdestotrotz ist es ein leichter Fehler, beides zu begehen.

    – autistisch

    3. Juni 2017 um 1:28 Uhr

  • Während diese Antwort beschreibt strtok‘s Einschränkungen im Vergleich zu richtigen Lexern, ich glaube nicht, dass es direkt erklärt, warum es so sein sollte veraltet (abgesehen von einer kurzen Erwähnung, dass “strtok sehr schlecht mit sich selbst komponiert”, ohne zu erklären warum es komponiert schlecht). Außerdem werden normalerweise veraltete Dinge aus der Standardbibliothek durch etwas anderes ersetzt (was im Fall von strtok wahrscheinlich wäre so etwas wie strtok_r oder strtok_s).

    – jamesdlin

    3. Juni 2017 um 4:57 Uhr


  • @jamesdlin Oder strsep oder eine Logik, die strcspn und memcpy als Bausteine ​​verwendet.

    – Random832

    3. Juni 2017 um 5:38 Uhr

  • @jamesdlin: Ich ermutige Sie, eine Antwort zu schreiben, die Ihnen besser gefällt, damit wir alle von Ihren Erkenntnissen profitieren können.

    – Eric Lippert

    5. Juni 2017 um 16:41 Uhr

Die Begrenzung von strtok(char *str, const char *delim) ist, dass es nicht mit mehreren Strings gleichzeitig arbeiten kann, da es einen statischen Zeiger zum Speichern des Index bis zum Analysieren beibehält (daher ausreichend, wenn jeweils nur mit einem String gespielt wird). Die bessere und sicherere Methode ist die Verwendung strtok_r(char *str, const char *delim, char **saveptr) die explizit einen dritten Zeiger nimmt, um den geparsten Index zu speichern.

  • Mit anderen Worten, es modifiziert von Natur aus nicht nur globaler Staataber versteckt Weltstaat!

    – Elchjungen

    2. Juni 2017 um 20:27 Uhr

  • Anders ausgedrückt, es ist kein Wiedereintritt.

    – Benutzer207421

    3. Juni 2017 um 6:21 Uhr

  • Anders gesagt, es ist in mehrfacher Hinsicht scheiße 🙂

    – ThingyWotsit

    4. Juni 2017 um 11:20 Uhr

1432800cookie-checkWarum sollte strtok() veraltet sein?

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

Privacy policy