-1

I'm trying to print some values on a string like this:

std::vector<std::string> data;    
data.push_back("One");
data.push_back("1");
const std::string & description = "This %s is number %s";

DWORD dwSize = data.size();

char szDescription[255 + 1];

for (DWORD i = 0; i < dwSize; ++i)
{
    _snprintf(szDescription, sizeof(szDescription), description.c_str(), data[i].c_str());
}

return szDescription;

However, when I print the string it returns me:

This One is number 124897566

I print the strings after snprintf and the second value is handled on the first iteration

Miguel Silva
  • 65
  • 2
  • 8

2 Answers2

1

An alternative solution for you is to replace the tokens in the std::string one by one. There are different solutions you could use (e.g., using regular expressions, using a library like fmt, etc.). Here is a simple example that uses basic std::string methods:

#include <iostream>
#include <vector>

std::string build() {
    std::vector<std::string> data;
    data.push_back("One");
    data.push_back("1");

    const std::string token = "%s";
    const std::string description = "This %s is number %s";

    std::string out = "";
    size_t start = 0;
    size_t end = description.find(token);
    int i = 0;
    while (end != std::string::npos) {
        out += description.substr(start, end - start);
        out += data[i++];
        start = end + token.length();
        end = description.find(token, start);
    }
    out += description.substr(start, end - start);

    return out;
}   

int main () {
    std::cout << build() << '\n';
    return 0;
}

This code prints:

This One is number 1
HugoTeixeira
  • 4,674
  • 3
  • 22
  • 32
1

Since this is C++, you can use std::ostringstream. The issue with _snprintf is that it is not type-safe (the input type must match the format specifier), and that it knows nothing about C++ objects such as std::string.

#include <sstream>
#include <string>
#include <vector>
#include <iostream>

std::string foo()
{
   std::vector<std::string> data;    
   data.push_back("One");
   data.push_back("1");
   std::ostringstream strm;
   std::string s;
   for (size_t i = 0; i < data.size(); ++i)
   {
      strm << "The " << data[i] << " is number " << i + 1;
      s = strm.str();
      std::cout << s << "\n";
      strm.str(""); 
   }
   return s;
}

int main()
{
    foo();
}

Output:

The One is number 1
The 1 is number 2

Live Example

PaulMcKenzie
  • 34,698
  • 4
  • 24
  • 45
  • Thank you for the string example but still doesn't reach the point of the question, the objective is to iterate for each value in the vector and format while format string appear, like %s, %d, etc.. @HugoTeixeira gave me the correct response till now – Miguel Silva Aug 17 '18 at 02:11
  • Your original question is not worded correctly or is not sufficient. There is no mention of the importance of keeping the format string. You are trying to hold onto `C` concepts, and the answer given is basically how to let go of those concepts. Also, look at the output produced in this answer and in the one given by HugoTeixera -- what is the difference? – PaulMcKenzie Aug 17 '18 at 02:18
  • Sorry i was quite sleepy, the objective is to format, not concatenate, assuming that the string and value is given by a text script that is parsed, thats why his example works for the question, however if there is a solution with `ostringstream` it would be better, without doing the splitting of course – Miguel Silva Aug 17 '18 at 09:53