0

我有一个函数,我需要为另一个日志记录函数返回时间,它看起来像这样:

//put time in to buf, format 00:00:00\0
void gettimestr(char buf[9]) {
  if(strlen(buf) != 9) { //experimental error checking
    fprintf(stderr, "Buf appears to be %d bytes and not 9!\n", strlen( buf ));
  }
  time_t cur_time;
  time(&cur_time);
  struct tm *ts = localtime(&cur_time);
  sprintf(buf, "%02d:%02d:%02d",
        ts->tm_hour,
        ts->tm_min,
        ts->tm_sec );
  strncat(buf, "\0", 1);
}

现在我想主要的问题是检查缓冲区是否足够长,sizeof() 返回一个指针大小,而 strlen 似乎在两个不同的调用中随机返回 0 或诸如 12 之类的东西。

我的第一个问题是,我怎样才能安全地检测缓冲区的大小,这可能吗?

我的另一个问题是,接受 buf[9] 是一种有利的方法还是应该接受指向缓冲区的指针,并使用 strcat() 而不是 sprintf() 来附加时间?sprintf 使时间值更容易填充零,尽管它似乎只接受字符数组而不接受指针。

4

2 回答 2

4

您的函数假定传入的缓冲区已经包含一个以空字符结尾的 9 个字符的字符串。那没有意义。

正确的方法是请求大小作为参数:

void gettimestr(char *buf, int bufferSize) {

并使用 snprintf:

snprintf(buf, bufferSize, "%02dx....", ....);<sub>*</sub>

并终止字符串,因为如果超出限制, snprintf 将不会这样做:

buf[bufferSize-1] = 0;

你可以这样调用你的函数:

char buffer[16];
gettimestr(buffer, sizeof(buffer));

没有其他方法可以确定大小。这不是数组知道其大小的 Java。传递 achar *只会将指针向下发送到函数而没有更多信息,因此获取缓冲区大小的唯一方法是要求调用者指定它。

(编辑:如评论中所指出的,snprintf 应始终正确终止字符串。)

于 2011-03-22T01:30:18.550 回答
0

@EboMike 是对的。只是为了补充他的答案,您可以检查缓冲区:

void gettimestr(char *buf, int bufferSize) {
    if (!buf) {
        fprintf(stderr, "Null buffer\n");
        return;
    }

 // rest of the code

 }
于 2011-03-22T01:35:24.523 回答