简体   繁体   English

像printf函数一样构建字符串

[英]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: 在plain c中有asprintf(),它将分配内存来保存结果字符串:

#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. 由于您已经标记了C ++,因此您可能希望使用C ++解决方案。

In C++: 在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() . 如果你需要底层的char const * ,比如说date.c_str()

The function std::to_string uses snprintf internally; 函数std::to_string内部使用snprintf ; 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. 在C ++中我写了一个函数来创建一个使用printf的格式化字符串。

Headerfile stringf.h : 头文件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: format函数的各种实现看起来像:

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. Boost有一个格式库 ,其工作方式略有不同。 It assumes you like cin , cout , and their ilk: 它假设你喜欢cincout和他们的同类:

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 : 最后,如果你想要一个C字符串( char* )而不是C ++ string ,你可以使用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 could even use vasprintf to make your own format function returning a C++ string: 您甚至可以使用vasprintf使您自己的format函数返回C ++字符串:

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. 还有一种方法可以两次调用vsnprintf ,第一种没有缓冲区来获取格式化的字符串长度,然后分配具有正确容量的字符串对象,然后第二次调用以获取字符串。 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. 在C语言中使用stdio.h头文件中的sprintf函数。

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

See here for more info. 有关详细信息,请参见此处

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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