开发者

Populating static string buffer in C via snprintf

开发者 https://www.devze.com 2023-02-13 06:09 出处:网络
I have some buffer and known size #define BUFFER_SIZE 1024*1024 char buffer[BUFFER_SIZE]; I must populate this buffer with some complex string.

I have some buffer and known size

#define BUFFER_SIZE 1024*1024
char buffer[BUFFER_SIZE];

I must populate this buffer with some complex string.

int populate_string(char *开发者_开发知识库buffer) {
    char *tbuffer = buffer;
    size_t tsize = BUFFER_SIZE;
    int rv;

    rv = snprintf(tbuffer, tsize, "foobar %s %d %s %D", ...);
    if (rv < 0) {
        printf("snprintf() error");
        return -1;
    } else if (rv >= tsize) {
        printf("overflow, increase buffer size");
        return -1;
    } else {
        tsize -= rv;
        tbuffer += rv;
    }

    // repeat snprintf's until string is fully populated

    return 0;
}

So, I have three questions:

  1. Is this the best way for dynamically populating static string?
  2. Is my way of populating string safe?
  3. How can I reduce number of lines? These return value checks take a lot of place, especially if there is lot of snprintfs.


  1. Depends on what you do with this strings then :) Obvious alternative is to use linked lists instead.
  2. Yes, it's safe.
  3. Sometimes there is no need to check whether it snprintf error or overflow - so you can use only one if() check.


open_memstream and fmemopen might be of interest for you:

http://linux.die.net/man/3/open_memstream

You can populate your buffer by opening a file stream to the buffer, i.e.:

FILE *f=fmemopen(buffer,BUFFER_SIZE,"w");
fwrite(f,...); 

Writing to this stream will yield an error (if you disable buffering) when you hit the ceiling of "buffer".

Also, you can use open_memstream to create a stream on a memory which automatically resizes to hold what you write to it.


It should be safe to use snprintf, assuming that the buffer length you are using is accurate. If the buffer length decreases, you would run into problems. Instead of using tsize to store the length of the buffer, have the caller pass in the buffer length as a parameter. That should make your function re-usable for different buffer sizes. You would still have to trust that the value provided by the caller is accurate, but I suppose you can't completely error-proof the function.

If you want to reduce your line count, combine multiple snprintf calls into one. That should reduce the number of error-checking blocks that are required. The drawback is you might run out of buffer midway through a string, but I don't think your current code protects against that either. To do that, you'd have to print to a temporary, internal string, measure that string's length, and then copy it to the output buffer if and only if there is enough room left.

0

精彩评论

暂无评论...
验证码 换一张
取 消