簡體   English   中英

像printf函數一樣構建字符串

[英]Build string as in printf function

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

我可以這樣做,但沒有印刷,喜歡

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

或者其他一些簡單的方法可以做到這一點?

在plain c中有asprintf(),它將分配內存來保存結果字符串:

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

(錯誤處理省略)

由於您已經標記了C ++,因此您可能希望使用C ++解決方案。

在C ++中:

#include <string>

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

如果你需要底層的char const * ,比如說date.c_str()

函數std::to_string內部使用snprintf ; 你也應該查找那個函數,因為它對格式化輸出來說是相當基礎的,你可以直接使用它,如果你真的認為你需要的話。

在C ++中我寫了一個函數來創建一個使用printf的格式化字符串。

頭文件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

用法:

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

format函數的各種實現看起來像:

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

所以你的例子是:

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

一種可能的實現如下所示。

Boost有一個格式庫 ,其工作方式略有不同。 它假設你喜歡cincout和他們的同類:

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

或者,如果你只是想要一個字符串:

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

請注意, %標志不是您習慣使用的標志。

最后,如果你想要一個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. */ }

您甚至可以使用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;
}

這不是非常有效,但它確實有效。 還有一種方法可以兩次調用vsnprintf ,第一種沒有緩沖區來獲取格式化的字符串長度,然后分配具有正確容量的字符串對象,然后第二次調用以獲取字符串。 這避免了兩次分配內存,但必須通過格式化的字符串進行兩次傳遞。

在C語言中使用stdio.h頭文件中的sprintf函數。

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

有關詳細信息,請參見此處

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM