sprintf неправильно заполняет буфер - PullRequest
0 голосов
/ 30 апреля 2020

Я использую write для создания CSV-файла со следующими типами значений в каждой строке

int16_t, int16_t, int16_t, int64_t, uint64_t

Сначала буфер заполняется с помощью sprintf и передается для записи. Однако есть только одна строка со всеми значениями в записанном файле. Нет новой строки.

static char line[34];



sprintf(line, "%d,%d,%d,%ld,%lu\n", ...);

write(fd_csv_data, line, sizeof(line));

% d,% d,% d,% ld,% lu в сумме составляет 32 байта, добавляя \ n и \ 0, в результате 34. Что я делаю не так?

Ответы [ 2 ]

2 голосов
/ 30 апреля 2020

Две проблемы:

  1. Вы пишете полный буфер, даже те части, которые идут после нулевого терминатора. Эта часть может быть неинициализированной и иметь неопределенные значения.
  2. Даже если вы полностью заполните буфер, вы пишете нулевой терминатор, который не должен записываться в текстовый файл.

Чтобы решить обе эти проблемы, используйте strlen вместо того, чтобы получить фактическую длину строки:

write(fd_csv_data, line, strlen(line));

В другой паре заметок :

  • Используйте snprintf вместо sprintf, чтобы избежать возможных переполнений буфера
  • Префикс размера l может быть неправильным для 64-битных типов, используйте стандартные константы формата , например PRId64 для int64_t.
0 голосов
/ 30 апреля 2020

Ваш буфер может переполниться, поэтому вам придется рассчитать максимальный размер сгенерированной строки или просто использовать достаточно большой буфер.

Чтобы записать в файл, вы можете использовать возвращаемое значение sprintf():

static char line[256];

int n = sprintf(line, "%d,%d,%d,%ld,%lu\n", ...);

write(fd_csv_data, line, n);    

В качестве альтернативы можно использовать более безопасный snprintf().

С некоторыми дополнительными проверками:

#define LINESIZE 256

static char line[LINESIZE];

int n = sprintf(line, "%d,%d,%d,%ld,%lu\n", ...);

if (n > 0 && n < LINESIZE) {

    write(fd_csv_data, line, n);    
}
// else..
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...