需要在没有预定义缓冲区大小的情况下用C ++构建字符串

时间:2013-10-03 21:27:22

标签: c++ arrays

我在Web上看到的所有使用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 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分: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();
}

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

答案 2 :(得分:2)

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

答案 3 :(得分:1)

您可以使用printf构建C ++字符串,就像使用实用程序函数调用一样:

#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对象在完成之前不会被破坏。)