7

time_t パラメータと任意の書式文字列を取り、それを書式設定する関数が必要です。私はこのようなものが欲しい:

std::string GetTimeAsString(std::string formatString, time_t theTime)
{
    struct tm *timeinfo;
    timeinfo = localtime( &theTime);

    char buffer[100];
    strftime(buffer, 100, formatString.c_str(), timeinfo);
    std::string result(buffer);
    return result;
}

ただし、私が直面している問題の 1 つは、バッファーの長さです。バッファ長として formatString * 4 のようなことを考えていました。しかし、バッファの長さを動的に設定することはできないと思いますか? 多分私は任意に大きなバッファを選ぶことができますか? 私はそれを一般的にする方法について少し立ち往生しています。

これを達成する関数をどのように書くことができますか?

4

5 に答える 5

5

C++11 を使用している場合:

std::string GetTimeAsString(std::string formatString, time_t theTime)
{
    struct tm *timeinfo;
    timeinfo = localtime( &theTime);

    formatString += '\a'; //force at least one character in the result
    std::string buffer;
    buffer.resize(formatstring.size());
    int len = strftime(&buffer[0], buffer.size(), formatString.c_str(), timeinfo);
    while (len == 0) {
        buffer.resize(buffer.size()*2);
        len = strftime(&buffer[0], buffer.size(), formatString.c_str(), timeinfo);
    } 
    buffer.resize(len-1); //remove that trailing '\a'
    return buffer;
}

注意: formatString を const 参照として (速度と安全性のために) 取り、結果の文字列をバッファーとして使用します。これは、後で追加のコピーを行うよりも高速です。また、フォーマット文字列と同じサイズから開始し、試行ごとにサイズを 2 倍にしますが、これは strftime の結果により適したものに簡単に変更できます。

于 2011-10-28T22:44:59.207 に答える
2

最善の策は、ほとんどの場合を処理する可能性が高い固定バッファーを提供し、残りの場合は特別な処理を行うことだと思います。次のようなもの(頭蓋骨内のウェットウェアを除いて、テストされていません):

std::string GetTimeAsString (std::string formatString, time_t theTime) {
    struct tm *timeinfo;
    char buffer[100], *pBuff = buffer;
    int rc, buffSize = 100;

    timeinfo = localtime (&theTime);
    rc = strftime(pBuff, 100, formatString.c_str(), timeinfo);

    // Most times, we shouldn't enter this loop.

    while (rc == 0) {
        // Free previous in it was allocated.

        if (pBuff != buffer)
            delete[] pBuff;

        // Try with larger buffer.

        buffSize += 100;
        pBuff = new char [buffSize];
        rc = strftime(pBuff, buffSize, formatString.c_str(), timeinfo);
    }

    // Make string then free buffer if it was allocated.

    std::string result(pBuff);
    if (pBuff != buffer)
        delete[] pBuff;

    return result;
}

strftime提供されたバッファが十分に大きくなかった場合、ゼロを返します。その場合、収まるまでより大きなバッファの割り当てを開始します。

割り当てられていないバッファサイズと割り当てサイズに使用する増分は、ニーズに合わせて調整できます。この方法には、まれなケースを除いて、効率の低下に気付かないという利点があります(ただし、小さい場合もあります)。その大部分には割り当てが行われません。

さらに、バッファサイズを増やすために、他の方法(+ 10%、2倍など)を選択することもできます。

于 2011-10-28T22:34:41.723 に答える
0

バッファのサイズが小さすぎて期待される結果を保持できない場合、strftime()関数は0を返します。このプロパティを使用すると、ヒープにバッファを割り当て、バッファが十分に大きくなるまで、サイズとして2の連続した累乗(1、2、4、8、16など)を試すことができます。2の累乗を使用する利点は、ソリューションの複雑さが結果の長さに対数的に比例することです。

考慮する必要のある特殊なケースもあります。結果のサイズが常に0になるような形式(たとえば、空の形式)である可能性があります。それをどのように処理するかわからない。

于 2011-10-28T22:36:18.630 に答える