boomvoyage21
boomvoyage21

Reputation: 1

sprintf does not fill the buffer correctly

I am using write to create a csv file with the following type of values on every line

int16_t, int16_t, int16_t, int64_t, uint64_t

First a buffer is filled using sprintf and the it is passed to write. However, there is only one line with all the values in the written file. No new line.

static char line[34];



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

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

%d,%d,%d,%ld,%lu makes 32 bytes in total, adding \n and \0 results in 34. What am I doing wrong ?

Upvotes: 0

Views: 581

Answers (2)

Danny_ds
Danny_ds

Reputation: 11406

Your buffer could overflow, so you'll have to calculate the maximum size of the generated string or just use a buffer big enough.

To write to the file, you can use the return value of sprintf():

static char line[256];

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

write(fd_csv_data, line, n);    

As an alternative the safer snprintf() could be used.

With some extra checks:

#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..

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409216

Two problems:

  1. You write the full buffer, even the parts that are after the null-terminator. This part could be uninitialized and have indeterminate values.
  2. Even if you fill the buffer completely, you write the null-terminator, which shouldn't be written to a text file.

To solve both these issues, use strlen instead to get the actual length of the string:

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

On another couple of notes:

  • Use snprintf instead of sprintf, to avoid possible buffer overruns
  • The size-prefix l might be wrong for 64-bit types, use the standard format macro constants, like PRId64 for int64_t.

Upvotes: 2

Related Questions