首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >合理的像snprintf一样的选择来代替strftime?

问合理的像snprintf一样的选择来代替strftime?
EN

Stack Overflow用户
提问于 2017-07-06 10:37:38
回答 1查看 1K关注 0票数 8

有什么标准(C,C++,POSIX,Linux.)strftime的替代方案,可用于

  1. 计算给定格式和时间的字符串缓冲区的所需大小,
  2. 如果缓冲区大小小于完整输出所需的大小,则截断输出(而不是像strftime那样保留未定义的数组内容)。

例如,接受snprintf格式字符串的日期/时间格式的-like语义将非常完美。

像std::put_time在C++11和更高版本中的函数不是一个选项,因为这些函数可能试图动态分配额外的内存,并可能抛出异常。

EN

回答 1

Stack Overflow用户

发布于 2017-07-06 14:37:13

可以继续尝试更大的缓冲区,直到代码成功为止(或者认为这太过了)。下面使用VLA (而不是C++),偷偷地避免“动态分配额外内存的尝试”-眨眼。

简单地分配一个大缓冲区,比如char buf[J_STRFTIME_MAX],对于实际的编码来说就足够了。@Michaël Roy和避免迭代方法。

代码语言:javascript
复制
#include <stdio.h>
#include <time.h>
#define J_STRFTIME_MAX 100

size_t j_strftime(char * s, size_t maxsize, const char * fmt, const struct tm * t) {
  size_t sz = strftime(s, maxsize, fmt, t);
  if (sz) {
    return sz;
  }
  size_t new_size = maxsize ? maxsize : 1;
  do {
    new_size *= 2;
    char new_s[new_size];
    sz = strftime(new_s, sizeof new_s, fmt, t);
    if (sz) {
      s[0] = 0;
      // strncat(s, new_s, maxsize);
      strncat(s, new_s, maxsize - 1);
      return strlen(new_s);
    }
  } while (sz < J_STRFTIME_MAX/2);
  return 0;
}

int main() {
  time_t now;
  time(&now);
  struct tm tm = *gmtime(&now);
  for (size_t i = 1; i < 30; i += 3) {
    char s[i];
    size_t sz = j_strftime(s, sizeof s, "%c", &tm);
    printf("%2zu %2zu <%s>\n", i, sz, s);
  }
}

输出

代码语言:javascript
复制
 1 24 <T>
 4 24 <Thu >
 7 24 <Thu Jul>
10 24 <Thu Jul  6>
13 24 <Thu Jul  6 14>
16 24 <Thu Jul  6 14:45>
19 24 <Thu Jul  6 14:45:00>
22 24 <Thu Jul  6 14:45:00 20>
25 24 <Thu Jul  6 14:45:00 2017>
28 24 <Thu Jul  6 14:45:00 2017>

非迭代

代码语言:javascript
复制
size_t j_strftime2(char * s, size_t maxsize, const char * fmt, const struct tm * t) {
  size_t sz = strftime(s, maxsize, fmt, t);
  if (sz == 0) {
    char new_s[J_STRFTIME_MAX];
    sz = strftime(new_s, sizeof new_s, fmt, t);
    if (sz == 0) {
      return 0;  // Too too big
    }
    s[0] = 0;
    // strncat(s, new_s, maxsize);
    strncat(s, new_s, maxsize - 1);
  }
  return sz;
}

编辑代码已更正。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44946592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档