Konvertieren Sie ein Präprozessor-Token in eine Zeichenfolge


70

Ich suche nach einer Möglichkeit, ein Präprozessor-Token in eine Zeichenfolge zu konvertieren.

Insbesondere habe ich irgendwo:

und ich möchte es verwenden, um ein Überlaufen des Puffers zu verhindern:

Ich bin offen für andere Wege, um das Gleiche zu erreichen, aber nur für die Standardbibliothek.



Antworten:


112

siehe http://www.decompile.com/cpp/faq/file_and_line_error_string.htm speziell:

So kann Ihr Problem gelöst werden sscanf(buf, "%" TOSTRING(MAX_LEN) "s", val);


3
Warum 2 Makros kaskadieren? Wäre nicht ein TOSTRING genug?
feedc0de

Siehe Antwort unten zur Stringifizierung mit doppelter Erweiterung. Der C / C ++ - Präprozessor ist schmutzig und hässlich und ich glaube ohne Standard. Warum es also zwei statt eins erfordert, konnte ich nicht sagen, weil ich nicht recherchieren möchte.
Dan

13
@Daniel Brunner Ein einzelnes Makro fügt das Token selbst "%" "MAX_LEN" "%"ein. Wenn Sie buchstäblich ein zweites Makro erhalten, wird der Token- Wert eingefügt, z. B. "16"weil das TOSTRINGMakro den endgültigen Code entsprechend macht STRINGIFY(16).
Tim Sylvester

@ TimSylvester Ich wünschte, ich könnte Ihnen einen Vertreter für diesen Kommentar geben! :)
Matthieu

23

Ich habe online eine Antwort gefunden.

Das Obige funktioniert nicht, zeigt aber hoffentlich, was ich tun möchte, dh, dass VERSION_STRING als "v4.47" endet.

Verwenden Sie so etwas wie, um die richtige numerische Form zu generieren


7

Es ist eine Weile her, aber das sollte funktionieren:

Wenn nicht, muss der Trick "doppelte Erweiterung" durchgeführt werden:


2
Der erste wird nicht funktionieren; # stringisiert Makroargumente in Makroerweiterungen. Der zweite wird funktionieren.
Jonathan Leffler

@RaviRaj - weil #nur Makroargumente stringisiert werden und sich die erste Zeile nicht im Hauptteil eines Makros befindet.
Jonathan Leffler

3

Sie sollten den String-Makrotrick mit doppelter Erweiterung verwenden. Oder haben Sie einfach eine

und halten Sie es synchron. (Das ist ein bisschen ärgerlich, aber solange die Definitionen direkt nebeneinander liegen, werden Sie sich wahrscheinlich daran erinnern.)

Eigentlich würde in diesem speziellen Fall nicht strncpyausreichen?

Wenn es jedoch printfso wäre, wäre dies einfacher:


1
Ja, ich wünschte, das * oder ein anderes Symbol wäre für längenbegrenzende Scanf-Routinen mit einem Argument verfügbar. sprintf in dieser Form funktioniert besser als strncpy, imo, da strncpy die Zeichenfolge nicht beendet, wenn sie den Puffer überschreitet, und zusätzliche Daten schreibt, wenn die Zeichenfolge zu kurz ist.
Davenpcj

1

Während einige der oben genannten "funktionieren", würde ich persönlich empfehlen, nur eine einfache String-API anstelle des Drecks zu verwenden, der in libc enthalten ist. Es gibt eine Reihe von portablen APIs, von denen einige auch für eine einfache Integration in Ihr Projekt optimiert sind ... und andere wie ustr haben einen geringen Speicherplatzaufwand und Unterstützung für Stapelvariablen .


0

Meine zwei Cent.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.