2

我在网上看到的所有使用 sprintf 创建字符串的示例都使用大小固定的静态声明数组。

#include <stdio.h>
#include <math.h>

int main()
{
   char str[80];

   sprintf(str, "Value of Pi = %f", M_PI);
   puts(str);

   return(0);
}

我希望能够以最简单的方式使用动态大小的数组来做到这一点。我必须编写一些代码来打印组成数组的值:

    printf("id=%s %s-array is: ", id.value(), name);
    for (unsigned int i = 0; i < depths.size(); i++) {
        printf("%f,", depths[i]);
    }
    printf("\n");

但我不想用单独的 printfs 来做这件事。我希望能够把它全部放在一个缓冲区中,该缓冲区适合我在运行时编写的字符串。我倾向于认为 sprintf 是做到这一点的最佳方式,但如果有其他函数我可以在 C++ 中使用。让我知道。

4

4 回答 4

5

惯用的 C++ 方式(正如@Troy 指出的那样)是使用字符串流:

#include <cmath>
#include <iostream>
#include <sstream>
#include <string>

int main()
{
   std::ostringstream ss;
   ss << "Value of Pi = " << M_PI;

   std::string str = ss.str();

   std::cout << str << '\n';

   return(0);
}
于 2013-10-03T21:36:29.913 回答
4

采用更惯用的方式并使用std::ostringstream

#include <sstream>
#include <iomanip>
#include <iostream>

int main()
{    
    std::ostringstream os;    
    os << "id=" << id.value() << " " << name << "-array is: ";
    for (unsigned int i = 0; i < depths.size(); i++) {
        os << std::fixed << depths[i] << ",";
    }    
    os << "\n";

    std::cout << os.str();
}

无需担心缓冲区大小或内存分配然后..

于 2013-10-03T21:38:04.490 回答
2

您可以使用字符串长度为零的 snprintf 来确定将打印多少个字符。然后,分配这个长度的缓冲区,并用分配的缓冲区重新遍历列表。

于 2013-10-03T21:34:24.367 回答
1

您可以使用带有实用功能的 -like 调用来构建 C++ 字符串printf,例如:

#include <cstdarg>
#include <string>
#include <vector>

std::string build_string(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    size_t len = vsnprintf(NULL, 0, fmt, args);
    va_end(args);
    std::vector<char> vec(len + 1);
    va_start(args, fmt);
    vsnprintf(vec.data(), len + 1, fmt, args);
    va_end(args);
    return std::string(vec.begin(), vec.end() - 1);
}

std::string msg = build_string("Value of Pi = %f", M_PI)将按预期工作,您可以使用c_str()传递对应char *的函数来期望它(只要您注意string对象在完成之前不会被破坏)。

于 2013-10-03T21:29:40.977 回答