简体   繁体   中英

Build string as in printf function

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

Can I do the same but without printing, smth like

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

Or maybe some other simple ways to do that?

In plain c there is asprintf() which will allocate memory to hold the resulting string:

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

(error handling omitted)

Since you have tagged C++ you probably want to use the C++ solutions.

In C++:

#include <string>

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

If you need the underlying char const * , say date.c_str() .

The function std::to_string uses snprintf internally; you should probably look up that function, too, as it is fairly fundamental to formatted output, and you can use it directly if you really think you need to.

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

Headerfile 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

Usage:

#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"
}

There are various implementations of a format function that looks something like:

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

so your example would be:

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

One possible implementation is shown below.

Boost has a format library that works a little differently. It assumes you like cin , cout , and their ilk:

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

Or, if you just wanted a string:

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

Note that % flags are not the ones you're used to.

Finally, if you want a C string ( char* ) instead of a C++ string , you could use the asprintf function :

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 could even use vasprintf to make your own format function returning 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;
}

This isn't terribly efficient, but it works. There also might be a way to call vsnprintf twice, the first with no buffer to get the formatted string length, then allocate the string object with the right capacity, then call the second time to get the string. This avoids allocating the memory twice, but has to make two passes through the formatted string.

In C language use sprintf function from stdio.h header file.

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

See here for more info.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM