5
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?

2
  • 1
    Which version of C++? In Visual C++, you have CString.Format for instance... Commented Apr 1, 2012 at 13:16
  • @MrLister thanks, that was helpful. In order to convert CString to char* one can use CString::GetBuffer(). Commented Apr 1, 2012 at 13:33

5 Answers 5

10

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Error handling being "if asprintf returns -1, instead of the length of the formatted string, it failed."
I wouldn't call it "plain C", asprintf is not a standard function.
Standard is what BSD has :) No seriously, "plain c" meant "not C++", and yes, IIRC you need to define _GNU_SOURCE on Linux (glibc actually) to get it.
3

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.

2 Comments

Note that this was added in C++11, so it may not be supported by all compilers and/or default build flags.
This avoids the entire purpose of the question, which was to use printf style syntax rather than plain string concatenation
2

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.

Comments

2

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

1 Comment

FWIW this is very slow. using asprintf and returning a string is ~3x faster, which returning a std::vector<char> is ~10% slower than that. Using reserve instead of resize is slightly faster
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.