Mit snprintf in einen cross-Plattform-Anwendung
Ich Schreibe ein C-Programm zu erwarten ist zusammengestellt mit allen wichtigen Compilern. Derzeit bin ich die Entwicklung von GCC auf einem linux-Rechner und kompiliert auf MSVC, bevor der code. Um die cross-Kompilierung einfach, ich bin kompilieren mit -ansi
und -pedantic
flags. Dies funktionierte gut, bis ich begann mit snprintf
ist nicht verfügbar in der C89-standard. GCC kompilieren kann, ohne dass das -ansi
- Schalter, aber MSVC scheitern wird immer als es nicht C99-Unterstützung.
Also ich hatte sowas wie,
#ifdef WIN32
#define snprintf sprintf_s
#endif
Dies funktioniert gut, weil snprintf
und sprintf_s
hat die gleichen Signaturen. Ich Frage mich, ist das der richtige Ansatz?
nicht
Nein.
Siehe Antwort von ähnlichen post link
snprintf
standard für alle C in jeder Plattform?Nein.
snprintf
ist Teil der C99-standard. MSVC nicht C99-Implementierung.sprintf_s
ist nicht gleichwertig. snprintf
gibt die Anzahl der Zeichen, wäre geschrieben worden, während sprintf_s
gibt -1 zurück, auf das abschneiden. Siehe diese Diskussion.Siehe Antwort von ähnlichen post link
InformationsquelleAutor Navaneeth K N | 2010-10-20
Du musst angemeldet sein, um einen Kommentar abzugeben.
Keine. Ihr Ansatz ist zum scheitern verurteilt.
sqrt
undcos
haben das gleiche Vorbild. Glaubst du, du kannst Sie tauschen in einem Programm und erhalten das gleiche Verhalten vor /nach der änderung?Sollten Sie wahrscheinlich schreiben Sie Ihre eigenen
snprintf
oder Sie laden sich eine Umsetzung aus dem internet (google ist dein Freund) und verwenden, dass sowohl in Linux und Windows.Diese Antwort ist nicht hilfreich. Die Frage in einer anderen Weise: Da die Funktionen snprintf und sprintf_s haben die gleiche Signatur, machen Sie auch die gleiche Funktionalität haben ? Deine Antwort sagt im Grunde: ich weiß es nicht.
InformationsquelleAutor pmg
Fand ich diese auf mit
_snprintf()
als eine alternative, und die Fallstricke beteiligten, wenn der Pufferüberlauf-Schutz tatsächlich löst. Von dem, was ich sehen konnte bei einem schnellen Blick, ähnliche Vorbehalte gelten fürsprintf_s
.Oh, und vergessen Sie nicht, schicken Sie eine mail an Microsoft fordern Sie unterstützen aktuelle Normen. (Ich weiß, dass Sie bereits angekündigt, Sie haben keinen plan zur Unterstützung von C99, aber Kerl Sie trotzdem. Sie haben es verdient.)
Bottom line, wenn Sie wollen, es zu spielen wirklich sicher ist, müssen Sie Ihre eigenen
snprintf()
(ein wrapper um_snprintf()
odersprintf_s()
fangen Ihre nicht-standard-Verhalten) für MSVC.*printf()
Umsetzung ist Recht groß.Eigentlich eine komplette
printf
Umsetzung kann sehr klein sein. Normalerweise würde ich Zustimmen, mit Ihrem Prinzip der Verpackung gebrochen-Implementierungen eher als reimplementing, aber seit Windows'*printf
hat auch einige kaputte Dinge nicht einfach zu wickeln, Weg (wie rückwärts interpretation von%s
und%ls
in der breiten Variante (N)), ich Frage mich gerade, ob " ersetzen, könnte der beste Ansatz sein.Eigentlich eine andere Sache, die Sie beheben können, gleichzeitig ist MS ' s ungenau-floating-point-Druck.
Ein naiv
*printf()
Umsetzung kann sehr klein sein. Ein komplett kann man sich schon etwas. Meine eigene Implementierung (zugegeben, geschrieben in einem nicht-sehr-knappen Stil) hat ein bisschen über 500 Zeilen schon, ohne - support für %e, %f, %g, wide chars, oder multibyte-format-strings.InformationsquelleAutor DevSolar
Dein Vorschlag kann funktionieren, wenn Sie sind vorsichtig. Das problem ist, dass die beiden Funktionen Verhalten sich etwas anders, wenn es das ist nicht ein problem für Sie, Sie sind gut zu gehen, sonst denken Sie über eine wrapper-Funktion:
Unterschiede zwischen MSVCs
_snprintf
und offizielle C99 (gcc,clang)snprintf
:Rückgabewert:
Schreibenden bytes:
Interessante
%n
Subtilität:Wenn Sie
%n
im code MSVC lassen es nicht initialisiertes! wenn es aufhört zu analysieren, weil die Puffer-Größe ist zu klein, GCC wird immer schreibt Anzahl von bytes, die wäre geschrieben worden, wenn Puffer gewesen wäre, groß genug ist.Also mein Vorschlag wäre zu schreiben Sie Ihre eigene wrapper-Funktion
mysnprintf
mitvsnprintf
/_vsnprintf
welche gibt die gleichen Werte zurück und schreibt die gleichen bytes auf beiden Plattformen (Vorsicht:%n
ist schwieriger zu beheben).InformationsquelleAutor eci
Sie öffnen konnte NUL spezielle Datei für MSVC und schreiben. Es wird Ihnen immer an, wie viele bytes benötigt werden, und nicht schreiben, nichts. Etwa so:
Sie sollten dann wissen, wie viele bytes zu reservieren, verwenden Sie sprintf erfolgreich.
InformationsquelleAutor Paul Humphreys
die vollständige Antwort (die Sie verbessern können, wenn Sie möchten), legen, die in einen Aufkleber
inline
und variadic-Funktionen sind in C99-features.ist eine Variable Funktion. Es hat schon eine Weile herum ... Also Nein, das ist kein C99 neben.
InformationsquelleAutor donthaveanaccount