mercredi 24 juin 2015

how to use sprintf on multiline raw string using named placeholders after building the string?

In Python or Perl or Ruby, one can build a multiline raw string (called HERE-DOCUEMNT sometimes) and then, after the string is build, replace some parts of the string (tokens using %s) inside the string, using named parameters. Similar to use sprintf on a string, except using names to help point to these locations inside the raw string.

This is very useful. I can only do part of the above in C++, but do not know if it is possible to do the string replacement using named place holders.

I'll show very simple example in Python, then show my attempt to do the same in C++

s=r"""
\begin{document}
\title{%(title)s}

This was written on %(date)s

And also updated on %(date)s and so on"""

print s % {"title": "main report","date": "1/1/2015"} 

The above prints

\begin{document}
\title{main report}

This was written on 1/1/2015

And also updated on 1/1/2015 and so on

In C++, the best I could do is this: (I have not programmed in C++ for long time, so this below I am sure can be improved in many ways)

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

int main()
{
        char buffer [500];
        string s =    
R"(
\begin{document}
\title{%s}

This was written on %s

And also updated on %s and so on
)";

        char *cstr = new char[s.length() + 1];
        strcpy(cstr, s.c_str());
        snprintf(buffer,500,cstr,"main report","1/1/2015","1/1/2015");
        cout<<buffer<<endl;
        return 0;
}

And now

>g++ -Wall -std=c++0x ./t1.cpp
>./a.out

\begin{document}
\title{main report}

This was written on 1/1/2015

And also updated on 1/1/2015 and so on

There are 2 problems: How to best do the sprintf without having to manually allocate buffer with correct size, to be able to hold the new string (after the replacement)?

Second problem, is it possible to do named replacement as in the example in Python? This way, if there are many place holders in the raw string, and some might be repeated in different locations, as with date in the above example, they all can be replaced at once.

Aucun commentaire:

Enregistrer un commentaire