Construct a string as in the printf function

printf("%d.%d.%d", year, month, day);

      

Is it possible to do the same, but without printing, for example

char* date = "%d.%d.%d", year, month, day;

      

Or maybe some other easy ways to do it?

+3


source to share


5 answers


Plain c has asprintf (), which will allocate memory to store the resulting string:

#include <stdio.h>
char *date;
asprintf(&date, "%d.%d.%d", year, month, day);

      



(processing error omitted)

Since you tagged C ++, you probably want to use C ++ solutions.

+5


source


In C ++:

#include <string>

std::string date = std::to_string(year) + '.' +
                   std::to_string(month) + '.' + std::to_string(day);

      



If you want a basic one char const *

, let's say date.c_str()

.

The function std::to_string

uses snprintf

internally; you should probably look for this feature as it is pretty fundamental to formatted output and you can use it directly if you really think you need it.

+2


source


There are various implementations of a function format

that looks something like this:

std::string format(const std::string& fmt, ...);

      

so your example:

std::string date = format("%d.%d.%d", year, month, day);

      

One possible implementation is shown below.

Boost has a library format that works a little differently. You are supposed to like cin

it cout

and their ilk:

cout << boost::format("%1%.%2%.%3%") % year % month % day;

      

Or, if you just want the line:

boost::format fmt("%1%.%2%.%3%");
fmt % year % month % day;
std::string date = fmt.str();

      

Please note that the flags are %

not what you are used to.

Finally, if you want to use a C ( char*

) string instead of C ++ string

, you can use the function asprintf

:

char* date; 
if(asprintf(&date, "%d.%d.%d", year, month, day) == -1)
{ /* couldn't make the string; format was bad or out of memory. */ }

      

You can even use vasprintf

to have your own function format

return a C ++ string:

std::string format(const char* fmt, ...)
{
    char* result = 0;
    va_list ap;
    va_start(ap, fmt);
    if(vasprintf(*result, fmt, ap) == -1)
        throw std::bad_alloc();
    va_end(ap);
    std::string str_result(result);
    free(result);
    return str_result;
}

      

It's not very efficient, but it works. There could also be a way to call vsnprintf

twice, the first one without a buffer to get the formatted length of the string, then allocate a string object with the required capacity, then call a second time to get the string. This avoids allocating memory twice, but you need to make two passes through the formatted string.

+1


source


In C ++, I wrote a function to create strings using printf format.

Header file stringf.h :

#ifndef STRINGF_H
#define STRINGF_H

#include <string>

template< typename... argv >
std::string stringf( const char* format, argv... args ) {
    const size_t SIZE = std::snprintf( NULL, 0, format, args... );

    std::string output;
    output.resize(SIZE+1);
    std::snprintf( &(output[0]), SIZE+1, format, args... );
    return std::move(output);
}

#endif

      

Using:

#include "stringf.h"

int main(){
    int year = 2020;
    int month = 12;
    int day = 20
    std::string date = stringf("%d.%d.%d", year, month, day);
    // date == "2020.12.20"
}

      

+1


source


In C, use a sprintf

function from stdio.h

a header file.

char  buffer[100];
sprintf(buffer,"%d.%d.%d", year, month, day);

      

See here for details .

0


source







All Articles