Frage

Ich suche nach einer Möglichkeit, einen Präprozessor -Token in eine Schnur umzuwandeln.

Insbesondere habe ich irgendwohin:

#define MAX_LEN 16

Und ich möchte es verwenden, um Pufferüberschreitungen zu verhindern:

char val[MAX_LEN+1]; // room for \0
sscanf(buf, "%"MAX_LEN"s", val);

Ich bin offen für andere Möglichkeiten, um dasselbe zu erreichen, aber nur die Standardbibliothek.

War es hilfreich?

Lösung

sehen http://www.decompile.com/cpp/faq/File_and_line_error_string.htmspeziell:

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)

Ihr Problem kann also gelöst werden, indem Sie dies tunsscanf(buf, "%" TOSTRING(MAX_LEN) "s", val);

Andere Tipps

Ich fand online eine Antwort.

#define VERSION_MAJOR 4
#define VERSION_MINOR 47

#define VERSION_STRING "v" #VERSION_MAJOR "." #VERSION_MINOR

Das obige funktioniert nicht, veranschaulicht aber hoffentlich, was ich tun würde, dh Version_String wird als "v4.47".

Um die richtige numerische Form zu generieren, verwenden Sie so etwas wie

#define VERSION_MAJOR 4
#define VERSION_MINOR 47

#define STRINGIZE2(s) #s
#define STRINGIZE(s) STRINGIZE2(s)
#define VERSION_STRING "v" STRINGIZE(VERSION_MAJOR) \
"." STRINGIZE(VERSION_MINOR)

#include <stdio.h>
int main() {
    printf ("%s\n", VERSION_STRING);
    return 0;
}

Es ist eine Weile her, aber das sollte funktionieren:

 sscanf(buf, "%" #MAX_LEN "s", val);

Wenn nicht, muss es "doppelte Expansion" -Trick:

 #define STR1(x)  #x
 #define STR(x)  STR1(x)
 sscanf(buf, "%" STR(MAX_LEN) "s", val);

Sie sollten den Doppel-Expansions-String-Makrotrick verwenden. Oder einfach eine haben

#define MAX_LEN    16
#define MAX_LEN_S "16"

char val[MAX_LEN+1];
sscanf(buf, "%"MAX_LEN_S"s", val);

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

Tatsächlich würde in diesem speziellen Fall nicht strncpy genügen?

strncpy(val, buf, MAX_LEN);
val[MAX_LEN] = '\0';

Wenn es wäre printf, Das wäre jedoch einfacher:

sprintf(buf, "%.*s", MAX_LEN, val);

Während einige der oben genannten "Arbeit" persönlich empfehlen, nur eine einfache String -API anstelle des Drecks zu verwenden, der in LIBC kommt. Es gibt eine Reihe tragbarer APIs, von denen einige auch für die einfache Einbeziehung in Ihr Projekt optimiert sind ... und einige mögen USTR Haben Sie winzige Raumaufwand und Unterstützung für Stapelvariablen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top