2

I want to create a public api that takes a string as an argument and places this string at the loaction where I have placed a format specifer in another string in that Api.

e.g. string PrintMyMessage( const string& currentValAsString)
     {
          string s1("Current value is %s",currentValAsString);
          return s1;
     }

Currently I am getting following build Error.

1>d:\extra\creatingstrwithspecifier\creatingstrwithspecifier\main.cxx(8): error C2664: 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(const std::basic_string<_Elem,_Traits,_Ax> &,unsigned int,unsigned int)' : cannot convert parameter 2 from 'const std::string' to 'unsigned int'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>,
1>              _Ax=std::allocator<char>
1>          ]
1>          No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

I just want to know what could be a better way to accomplish this task.

Apoorva sahay
  • 1,900
  • 3
  • 28
  • 45

4 Answers4

2

As discussed also in this rather similar question, you could use the Boost Format Library. For example:

std::string PrintMyMessage( const string& currentValAsString )
{
  boost::format fmt = boost::format("Current value is %s") % currentValAsString; 
  // note that you could directly use cout:
  //std::cout << boost::format("Current value is %s") % currentValAsString;
  return fmt.str();
}

In the answers to the other question you can also find other approaches, e.g. using stringstreams, snprintf, or string concatenation.

Here's a complete generic example:

#include <string>
#include <iostream>
#include <boost/format.hpp>

std::string greet(std::string const & someone) {
    boost::format fmt = boost::format("Hello %s!") % someone;
    return fmt.str();
}

int main() {
    std::cout << greet("World") << "\n";
}

Or, if you can't or don't want to use Boost:

#include <iostream>
#include <string>
#include <vector>
#include <cstdio>

std::string greet(std::string const & someone) {
    const char fmt[] = "Hello %s!";
    std::vector<char> buf(sizeof(fmt)+someone.length());
    std::snprintf(&buf[0], buf.size(), fmt, someone.c_str());
    return &buf[0];
}

int main() {
    std::cout << greet("World") << "\n";
}

Both examples produce the following output:

$ g++ test.cc && ./a.out
Hello World!
Community
  • 1
  • 1
moooeeeep
  • 31,622
  • 22
  • 98
  • 187
  • How does this work under the hood? valist? – Dennis Jun 11 '12 at 10:35
  • [All in all, the format class translates a format-string (with eventually printf-like directives) into operations on an internal stream, and finally returns the result of the formatting, as a string, or directly into an output stream.](http://www.boost.org/doc/libs/1_49_0/libs/format/doc/format.html#how_it_works) – moooeeeep Jun 11 '12 at 11:50
  • This didn't work out of the box for me... – Jonny Apr 23 '15 at 08:00
  • @Jonny I added more examples. I assume your build environment didn't include the necessary Boost library. Also have a look at my other example if you can't or don't want to use Boost. – moooeeeep Apr 23 '15 at 17:01
0
string PrintMyMessage( const string& currentValAsString)
{
    char buff[100];
    sprintf(buff, "Current value is %s", currentValAsString.c_str());

    return buff;
}
PermanentGuest
  • 5,213
  • 2
  • 27
  • 36
0
string PrintMyMessage(const char* fmt, ...)
{
    char buf[1024];
    sprintf(buf, "Current value is ");

    va_list ap;
    va_start(ap, fmt);
    vsprintf(buf + strlen(buf), fmt, ap);

    return buf;
}

string str = PrintMyMessage("Port is %d, IP is :%s", 80, "192.168.0.1");
Aladdin
  • 171
  • 8
  • You should initialise your buffer with `={0}` and there is a vsnprintf template with for ensuring the buffer is not overflown. – Dennis Jun 11 '12 at 10:33
  • You are right, actually, 1024 size buffer may be a potential bug:) – Aladdin Jun 13 '12 at 02:21
-2

You can simply write this:

return  "Current value is " + currentValAsString;
Nawaz
  • 353,942
  • 115
  • 666
  • 851