В C есть несколько способов сделать это, в зависимости от того, как вы хотите выделить память [*]. Для простого варианта выделения его из кучи:
len = snprintf(0, 0, "%d bottles, %d shelves, room %d\n", one, two, three);
char *result = malloc(len+1);
if (result == 0) { /* handle error */ }
snprintf(result, len+1, "%d bottles, %d shelves, room %d\n", one, two, three);
/* some time later */
free(result);
Остерегайтесь нестандартных реализаций snprintf
, которые не возвращают длину при превышении буфера. Проверьте свою документацию.
В C ++ snprintf
не входит в стандарт, и даже там, где он доступен, приведенный выше код должен приводить к результату malloc [**]. C ++ добавляет возможность использования строковых потоков:
std::stringsteam r;
r << one << " bottles, " << two << " shelves, room " << three << "\n";
std::string result = r.str();
// if you absolutely need a char*, use result.c_str(), but don't forget that
// the pointer becomes invalid when the string, "result" ceases to exist.
Это экономит беспорядок при длине буфера, упрощает управление ресурсами и позволяет избежать риска с printf
и друзьями, что вы можете передать аргумент неправильного типа для спецификатора формата. Обычно это предпочтительный вариант.
Однако в некоторых случаях он менее гибок: формат встроен в код, а не содержится в строке формата, поэтому сделать текст настраиваемым сложнее. Это также может быть немного сложнее для чтения, например, это не редкость, когда в первой версии любой такой строки кода пропускается символ пробела. Но если вы хотите использовать подход snprintf
в C ++, а в вашей реализации доступен snprintf
, то вы можете воспользоваться преимуществами более простого управления памятью в C ++ следующим образом:
len = std::snprintf(0, 0, "%d bottles, %d shelves, room %d\n", one, two, three);
std::vector<char> r(len+1);
std::snprintf(&r[0], r.size(), "%d bottles, %d shelves, room %d\n", one, two, three);
char *result = &r[0];
// again, "result" is only valid as long as "r" is in scope
[*] Обратите внимание, что вы не можете «сохранить» строку в char*
, потому что char*
- это просто указатель. Вы можете хранить указатель на строку в char*
, но сама строка - это совершенно отдельная вещь.
[**], потому что C и C ++ РАЗНЫЕ ЯЗЫКИ!