C:一种更安全的方法来检查函数中的缓冲区并附加到它?

发布于 2024-10-24 12:35:11 字数 749 浏览 7 评论 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 使向时间值填充零变得更容易,尽管它似乎只接受字符数组而不接受指针。

I have a function of which I need to return the time for another logging function, and it looks like this:

//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);
}

Now I guess the main problem is checking if the buffer is long enough, sizeof() returns a pointer size and strlen seems to randomly return 0 or something such as 12 on two different calls.

My first question is, how would I be able to detect the size of the buffer safely, is it possible?

My other question is, is accepting buf[9] a favourable method or should I accept a pointer to a buffer, and use strcat() instead of sprintf() to append the time to it? sprintf makes it easier for padding zeros to the time values, although it seems to only accept a character array and not a pointer.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

停顿的约定 2024-10-31 12:35:11

您的函数假设传入的缓冲区已包含一个包含 9 个字符的以 null 结尾的字符串。这没有道理。

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

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 中数组知道其大小的情况。传递 char * 只会向函数发送一个指针,而无需进一步的信息,因此获取缓冲区大小的唯一方法是要求调用者指定它。

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

Your function assumes that the buffer being passed in already contains a null-terminated string with 9 characters. That doesn't make sense.

The proper way would be to request the size as an argument:

void gettimestr(char *buf, int bufferSize) {

and use snprintf:

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


And terminate the string since snprintf won't do that if you exceed the limit:

buf[bufferSize-1] = 0;


You can call your function like this:

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

There is no other way to determine the size. This isn't Java where an array knows its size. Passing a char * will simply send a pointer down to the function with no further information, so your only way to get the size of the buffer is by requiring the caller to specify it.

(EDIT: snprintf should always terminate the string properly, as pointed out in the comments.)

笑叹一世浮沉 2024-10-31 12:35:11

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

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

 // rest of the code

 }

@EboMike is right. Just to complement his answer, you could check the buffer with:

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

 // rest of the code

 }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文