'strncpy' vs. 'sprintf'
Kann ich sehen, viele sprintf
's in meinen Anwendungen für das kopieren eines Strings.
Ich habe ein Zeichen-array:
char myarray[10];
const char *str = "mystring";
Nun, wenn ich wollen möchten, kopieren Sie die Zeichenfolge str
in myarray
ist besser:
sprintf(myarray, "%s", str);
oder
strncpy(myarray, str, 8);
?
InformationsquelleAutor der Frage Vijay | 2012-09-05
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sollten nicht verwendet werden, überhaupt.
sprintf
ist gefährlich, veraltet und ersetzt durchsnprintf
. Der einzige Weg, um die altensprintf
sicher mit der string-Eingänge ist entweder Messen Ihre Länge vor dem Aufrufsprintf
die ist hässlich und fehleranfällig) oder indem Sie ein Feld hinzufügen genauigkeitsangabe (z.B.%.8s
oder%.*s
mit einem zusätzlichen integer-argument für die Beschränkung der Größe). Dies ist auch hässlich und fehleranfällig, insbesondere wenn mehr als ein%s
Planer beteiligt ist.strncpy
ist auch gefährlich. Es ist nicht eine Puffer-Größe-eingeschränkte version vonstrcpy
. Es ist eine Funktion zum kopieren von Zeichen in einem festen Länge, null-gepolsterte (im Gegensatz zu null-beendet) array, wo die Quelle kann entweder ein C-string oder ein fixed-length character-array mindestens so groß ist wie das Ziel. Ihr Verwendungszweck war für legacy-unix-Verzeichnis, Tabellen -, Datenbank-Einträge, etc. das klappte mit fester Größe, text-Felder, und wollte nicht zu verschwenden, sogar ein einzelnes byte auf der Festplatte oder im Speicher für den null-Terminierung. Es kann missbraucht werden als Puffer-Größe-limitedstrcpy
aber tun so schädlich ist, aus zwei Gründen. Zuerst von allen, es nicht zu null zu kündigen, wenn der ganze Puffer für die string-Daten (d.h. wenn der Quell-string-Länge ist mindestens so lang wie die dest-Puffer). Können Sie die Kündigung zurück nehmen, aber das ist hässlich und fehleranfällig. Und zweitensstrncpy
immer pads die volle Ziel-Puffer mit null-bytes, wenn die Zeichenkette kürzer ist als der output-Puffer. Das ist einfach eine Verschwendung von Zeit.Also, was sollte man stattdessen verwenden?
Einige Leute wie die BSD
strlcpy
Funktion. Semantisch, es ist identisch mitsnprintf(dest, destsize, "%s", source)
außer dass der Rückgabewert istsize_t
und es nicht zu verhängen eine künstlicheINT_MAX
limit auf string-Länge. Jedoch, die meisten populären nicht-BSD-Systemen fehlenstrlcpy
und es ist leicht zu machen gefährliche Fehler beim schreiben Ihrer eigenen, so dass, wenn Sie es verwenden möchten, sollten Sie einen sicheren, bekannten funktionierenden version aus einer vertrauenswürdigen Quelle.Meine Präferenz ist, einfach
snprintf
für alle nicht trivialen string-Konstruktion, undstrlen
+memcpy
für einige triviale Fälle, die gemessen worden sind, werden performance-kritisch. Wenn Sie in die Gewohnheit der Verwendung dieser Redewendung richtig, es wird fast unmöglich, versehentlich schreiben Sie code mit string-bezogene Sicherheitslücken.InformationsquelleAutor der Antwort R..
Den verschiedenen Versionen von printf/scanf sind unglaublich langsam-Funktionen, für die der folgenden Gründe:
Verwenden Sie variable argument-Listen, das macht die übergabe von Parametern komplexer. Dies geschieht durch verschiedene obskure Makros und Zeiger. Alle Argumente müssen analysiert werden, zur Laufzeit zu bestimmen, Ihre Typen, die zusätzlichen overhead-code. (VA-Listen ist durchaus auch eine redundante Funktion der Sprache, und auch gefährlich, wie es farweaker Typisierung als plain-parameter übergeben.)
Müssen Sie verarbeiten eine Menge von komplexen Formatierungen und alle verschiedenen Arten unterstützt. Dies fügt viel Aufwand, um die Funktion auch. Da alle Typ-Bewertungen werden in der Laufzeit, der compiler nicht optimieren entfernt Teile der Funktion, die nie verwendet werden. Also, wenn Sie nur wollte, zu drucken, die ganzen zahlen mit printf(), erhalten Sie support für float-zahlen, komplexe Arithmetik, string-handling etc etc mit Ihrem Programm, als Reine Verschwendung von Speicherplatz.
Funktionen wie strcpy() und vor allem memcpy (), auf der anderen Seite, sind stark optimiert durch den compiler oft in inline montieren für maximale Leistung.
Einige Messungen, die ich mal gemacht auf barebone-16-bit-low-end-mikrocontroller sind unten aufgeführt.
Als ein rule von Daumen sollten Sie nie verwenden stdio.h in jeder form der Produktion von code. Es ist, als debugging/testing-library. MISRA-C:2004-Verbote stdio.h im Produktions-code.
BEARBEITEN
Ersetzt subjektive zahlen mit Fakten:
Messungen von strcpy versus sprintf am Ziel, Freescale HCS12, compiler von Freescale
Codewarrior 5.1. Mit C90 Implementierung von sprintf, C99 wäre mehr wirkungslos noch. Alle Optimierungen aktiviert. Der folgende code wurde getestet:
Ausführungszeit, einschließlich der parameter mischen on/off call stack:
Programm/ROM-Speicherplatz:
RAM/stack-Speicherplatz:
Zahl der internen Funktionsaufrufe:
Funktion " call-stack Tiefe:
InformationsquelleAutor der Antwort Lundin
Würde ich nicht verwenden, sprintf, nur um eine Zeichenfolge kopieren. Es ist overkill, und jemand, der liest, der code würde sicherlich zu stoppen und Frage mich, warum ich dies Tat, und ob Sie (oder ich) etwas fehlt.
InformationsquelleAutor der Antwort Thomas Padron-McCarthy