C: более безопасный способ проверить буфер в функции и добавить к нему? - PullRequest
0 голосов
/ 22 марта 2011

У меня есть функция, из которой мне нужно вернуть время для другой функции регистрации, и это выглядит так:

//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 упрощает заполнение нулей значениями времени, хотя, похоже, он принимает только массив символов, а не указатель.

Ответы [ 2 ]

4 голосов
/ 22 марта 2011

Ваша функция предполагает, что передаваемый буфер уже содержит строку с нулем в конце с 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, где массив знает свой размер.Передача char * просто отправит указатель на функцию без дополнительной информации, поэтому ваш единственный способ получить размер буфера - попросить вызывающего его указать.

(EDIT: snprintfвсегда завершайте строку правильно, как указано в комментариях.)

0 голосов
/ 22 марта 2011

@ EboMike прав.Просто чтобы дополнить его ответ, вы можете проверить буфер с помощью:

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

 // rest of the code

 }
...