当snprintf返回的值大于其size参数时,如何获取格式化输出的最后一个字符?

时间:2019-01-18 21:46:24

标签: c printf

我有一个65535个字符长的缓冲区。我需要将格式化的输出打印到缓冲区。问题是:如果格式化后的输出大小大于65535,我希望将其最后一个字符存储在缓冲区中,而不是像snprintf那样丢弃前一个字符,而不是其余的字符。 / p>

我考虑过实现snprintf逻辑,但是要从字符串的末尾而不是开头开始。

有没有更简单的方法来做到这一点?

1 个答案:

答案 0 :(得分:1)

解决方案是:

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>

int snprintfEnd(char *str, size_t size, const char *format, ...)
{
  va_list ap1, ap2;

  va_start(ap1, format);
  va_copy(ap2, ap1);

  /* get length of all */
  int sz = vsnprintf(0, 0, format, ap2);

  va_end(ap2);

  /* get all */
  char * all = malloc(sz + 1);

  vsprintf(all, format, ap1);
  va_end(ap1);

  /* copy the expected part */
  int r;

  if (sz < size) {
    strcpy(str, all);
    r = sz;
  }
  else {
    strcpy(str, all + sz - size);
    r = size;
  }

  free(all);
  return r;
}

int main()
{
  char s[6];

  int ln = snprintfEnd(s, 5, "%d %d %d", 1, 234, 567);

  printf("%d : '%s'\n", ln, s);

  return 0;
}

执行:

5 : '4 567'