Pergunta

Estou procurando uma maneira de converter um token de pré-processador em uma string.

Especificamente, em algum lugar tenho:

#define MAX_LEN 16

e quero usá-lo para evitar sobrecarga de buffer:

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

Estou aberto a outras maneiras de realizar a mesma coisa, mas apenas na biblioteca padrão.

Foi útil?

Solução

Vejo http://www.decompile.com/cpp/faq/file_and_line_error_string.htmespecificamente:

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

Portanto, seu problema pode ser resolvido fazendosscanf(buf, "%" TOSTRING(MAX_LEN) "s", val);

Outras dicas

Encontrei uma resposta online.

#define VERSION_MAJOR 4
#define VERSION_MINOR 47

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

O exposto acima não funciona, mas espero que ilustre o que eu gostaria de fazer, ou seja, faça o versão_string acabar como "v4.47".

Para gerar a forma numérica adequada, use algo como

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

Já faz um tempo, mas isso deve funcionar:

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

Caso contrário, precisará "dobrar a expansão" do truque:

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

Você deve usar o truque de macro de cordas de expansão dupla. Ou apenas ter um

#define MAX_LEN    16
#define MAX_LEN_S "16"

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

e mantenha -o sincronizado. (Isso é um pouco incômodo, mas enquanto as definições estiverem próximas uma da outra, você provavelmente se lembrará.)

Na verdade, neste caso em particular, não seria strncpy satisfazer?

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

Se isso fosse printf, porém, isso seria mais fácil:

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

Embora algumas das opções acima "funcionem", pessoalmente eu recomendo apenas usar uma API de string simples em vez do lixo que vem na libc.Existem diversas APIs portáteis, algumas das quais também são otimizadas para facilitar a inclusão em seu projeto...e alguns como usuário tem pequena sobrecarga de espaço e suporte para variáveis ​​de pilha.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top