Domanda

Sto cercando un modo per convertire un token preprocessore in una stringa.

In particolare, da qualche parte ho:

#define MAX_LEN 16

e voglio usarlo per prevenire il sovraccarico del buffer:

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

Sono aperto ad altri modi per realizzare la stessa cosa, ma solo libreria standard.

È stato utile?

Soluzione

vedi http://www.decompile.com/cpp/faq/file_and_line_error_string.htm in particolare:

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

quindi il tuo problema può essere risolto facendo sscanf (buf, "% " TOSTRING (MAX_LEN) " s " ;, val);

Altri suggerimenti

Ho trovato una risposta online.

  
#define VERSION_MAJOR 4
#define VERSION_MINOR 47

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

Quanto sopra non funziona ma si spera     illustra cosa mi piacerebbe fare     ovvero fare in modo che VERSION_STRING finisca come     & Quot; v4.47 ".

  
     

Per generare la forma numerica corretta   usa qualcosa come

#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;
}

È passato del tempo, ma dovrebbe funzionare:

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

In caso contrario, dovrà essere "doppia espansione". trucco:

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

Dovresti usare il trucco macro di stringificazione a doppia espansione. O semplicemente avere un

#define MAX_LEN    16
#define MAX_LEN_S "16"

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

e mantienilo sincronizzato. (È un po 'fastidioso, ma finché le definizioni sono una accanto all'altra, probabilmente ti ricorderai.)

In realtà, in questo caso particolare, strncpy è sufficiente?

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

Se fosse printf , tuttavia, sarebbe più semplice:

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

Mentre alcuni dei precedenti "funzionano", personalmente consiglierei semplicemente di usare una semplice API stringa invece del dreck che viene fornito in libc. Esistono numerose API portatili, alcune delle quali sono anche ottimizzate per facilitare l'inclusione nel progetto ... e altre come ustr ha un sovraccarico di spazio ridotto e supporto per le variabili dello stack.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top