什么是确定strftime char数组最大大小的智能方法?

时间:2015-05-15 22:27:38

标签: c++ strftime mktime

如何在没有反复试验的情况下为strftime调整char数组的大小?使用mktime,示例中的时间戳大小N必须大于86,否则我将获得任意日期。 例如

N = 86 2013-07-13 02:41

N = 82 1979-05-18 13:23

如何在事先不知道日期的情况下有效地扩展N?检查> 0没有帮助。

#include <iostream>
#include <cstring>
#include <ctime>

#define N 86

using namespace std;

int main(void)
{
time_t t;
struct tm ts;
char timestamp[N] ;

ts.tm_min    = 41;     
ts.tm_hour   = 2;     
ts.tm_mday   = 13;
ts.tm_mon    = 7 - 1;      
ts.tm_year   = 13 - 1900 + 2000;         

t = mktime(&ts);

if (strftime(timestamp, sizeof(timestamp)-1, "%Y-%m-%d %H:%M", &ts) > 0)
    cout << timestamp;
else {
    cerr << "strftime failed." <<endl;
    return 1;
}

return 0;
}

2 个答案:

答案 0 :(得分:0)

来自strftime的文档:

  

如果生成的C字符串的长度(包括终止空字符)不超过maxsize,则该函数返回复制到ptr的字符总数(不包括终止空字符)。否则,它返回零,并且ptr指向的数组的内容是不确定的。

这意味着如果您不知道大小并且可以动态分配字符串,您可以按照以下方式执行操作:

int size = N; //  Some starting size
char *timestamp = malloc(size);

//  Your time stuff

int result = strftime(timestamp, size - 1, "%Y-%m-%d %H:%M", &ts);

// While there isn't enough room to store the result
while (result == 0)
{
  free(timestamp);  //  Free old data
  size *= 2;        //  Double the size (should be more than enough)
  timestamp = malloc(size); //  Allocate the new size. You can check for failed allocations here as well.

  //  Retry
  result = strftime(timestamp, size - 1, "%Y-%m-%d %H:%M", &ts);
}

std::cout << timestamp;

答案 1 :(得分:0)

因为您将其标记为C ++,所以您可能会考虑以下内容。

- &GT;请注意,这里的字符串大小没有任何困难。

// function to create a timestamp style string 
std::string   yyDmmDdd_hhCmmGet(time_t tt)
{
   std::stringstream ss;
   // goal - something like:  "%Y-%m-%d %H:%M"
   {
      struct tm mybdtod; // linux api: my broken down time of day

      // the following is a relatively slow function
      ::localtime_r (&tt, &mybdtod);
      // linux api - convert time_t to tm as local time

      ss << std::setw(4) << (mybdtod.tm_year+1900) 
         << "-"
         << std::setfill('0') << std::setw(2) << mybdtod.tm_mon+1 
         << "-"
         << std::setfill('0') << std::setw(2) <<  mybdtod.tm_mday   
         << " ";

      ss << std::dec << std::setfill('0')  << std::setw(2) 
         << mybdtod.tm_hour 
         << ":"
         << std::setfill('0')  << std::setw(2) 
         << mybdtod.tm_min;
   }
   return(ss.str());
}


int t186(void)
{
   struct tm ts; // linux api: time struct
   ::memset(&ts, 0, sizeof(tm));

   ts.tm_min    = 41;
   ts.tm_hour   = 3-1;
   ts.tm_mday   = 13;
   ts.tm_mon    = 7 - 1;
   ts.tm_year   = 13 - 1900 + 2000;

   time_t tt = mktime(&ts); // linux api: Convert tm struct to time_t

   // format time_t to string
   std::string s = yyDmmDdd_hhCmmGet(tt); // timestamp style

   std::cout << "\n" << s 
             << "\n            s.size(): " 
             << s.size() << " chars" << std::endl;

   // now we know how many chars timestamp needs 

   // add 1 to size because ?strftime seems to need it?
   char timestamp[s.size()+1];  

   (void)strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M", &ts);
   // linux api: format time_t to string

   std::cout << "\n" << timestamp << std::endl;
   std::cout << "   sizeof(timestamp): " 
             << sizeof(timestamp) << " chars" << std::endl;

   return(0);
 }