Вопрос

Я ищу способ преобразования токена препроцессора в строку.

В частности, я где-то получил:

#define MAX_LEN 16

и я хочу использовать его для предотвращения переполнения буфера:

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

Я открыт для других способов достижения того же, но только для стандартной библиотеки.

Это было полезно?

Решение

см. http://www.decompile.com/cpp/faq/file_and_line_error_string.htm а именно:

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

так что ваша проблема может быть решена с помощью sscanf (buf, "% " TOSTRING (MAX_LEN) " s " ;, val);

Другие советы

Я нашел ответ в Интернете.

  
#define VERSION_MAJOR 4
#define VERSION_MINOR 47

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

Выше не работает, но, надеюсь,     иллюстрирует то, что я хотел бы сделать,     т.е. сделать VERSION_STRING в итоге     & Quot; v4.47 & Quot;.   

     

Для генерации правильной числовой формы   использовать что-то вроде

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

Это было давно, но это должно сработать:

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

Если нет, то потребуется "двойное расширение" Хитрость:

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

Вы должны использовать трюк макросов с двойным расширением. Или просто есть

#define MAX_LEN    16
#define MAX_LEN_S "16"

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

и синхронизируйте его. (Это немного беспокоит, но пока определения находятся рядом друг с другом, вы, вероятно, помните.)

На самом деле, в данном конкретном случае, strncpy будет недостаточно?

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

Если бы это был printf , это было бы проще:

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

Хотя некоторые из вышеперечисленных «работают», лично я бы порекомендовал просто использовать простой строковый API вместо dreck, который есть в libc. Существует ряд переносимых API, некоторые из которых также оптимизированы для простоты включения в ваш проект ... а некоторые, например, У ustr небольшие накладные расходы и поддержка переменных стека.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top