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.

davenpcj
quelle
stackoverflow.com/questions/195975/…
Ciro Santilli 5 冠状 冠状 病 六四 事件 5.
Mögliches Duplikat von C-Makros zum Erstellen von Zeichenfolgen
Richard Stelling

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);

Dan
quelle
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

davenpcj
quelle
7

Es ist eine Weile her, aber das sollte funktionieren:

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

James Curran
quelle
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:

kurzlebig
quelle
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 .

James Antill
quelle
0

Meine zwei Cent.

Joma
quelle