【问题标题】:how to get append mode in sprintf()如何在 sprintf() 中获取附加模式
【发布时间】:2012-04-24 09:16:04
【问题描述】:

查看此代码:

int main() {
    char a[50];
    FILE *fp;

    fp = fopen("test1.txt", "w");

    sprintf(a,"jigar %d \n", 3);
    fprintf(fp,"jigar %d \n", 3);

    sprintf(a,"patel %d \n", 2);
    fprintf(fp,"patel %d \n", 2);
    printf("%s", a);
}

这里,使用fprintf,我可以写入文件

jigar 3 
patel 2 

我想要的相同功能在哪里我打印的任何东西都放在一个字符缓冲区中。

但是使用sprintf 会给我缓冲区

patel 2 

我有很多这样的打印,我想在一个字符缓冲区中添加,然后我需要将它返回给应用程序,那么如何以最简单和最快的方式获得它?

【问题讨论】:

  • 手动管理 C 中的所有内容 == 痛苦。但我告诉你,它会很快。
  • 哦,是的,对不起,这是我的拼写错误

标签: c string printf


【解决方案1】:

sprintf() 返回打印的字符数。

只需使用该数字进行下一次写入...

int i;
char a[50];
char *ap = a;

for (i = 5; i < 15; i++) {
    ap += sprintf(ap, "%d ", i);
}

printf("%s\n", a); /* "5 6 7 8 9 10 11 12 13 14 " */

请确保您不会导致任何缓冲区溢出。

【讨论】:

  • 我所做的是:int offset = 0; offset += snprintf(ap, sizeof(ap) - offset, ...);
  • @Folkert:snprintf() 假定为 C99。有些人坚持使用 C89。好主意。
  • @FolkertvanHeusden,基本上是一个很好的建议,但有一些错误。你不增加ap,sizeof(ap) 是没有意义的,一旦偏移量变得太大,你会给snprintf 一个负大小。更好的是offset += snprintf(ap+offset, sizeof(a)&gt;offset?sizeof(a)-offset:0, ...);
【解决方案2】:

这个想法是给 sprintf 指向缓冲区基址的指针 + 偏移量。追加时偏移会变大。

通过使用 strlen 可以获得当前'string'的长度。为了避免缓冲区溢出,我们可以添加额外的逻辑来检查当前'string' + '新字符串'小于缓冲区的大小。

size_t offset = strlen(text);
sprintf(&(text[offset]), "This is how You append using sprintf");

循环内的示例:

char text[255];
text[0] = '\0';
for(int i = 0 ; i < 10 ; i++) {
    size_t offset = strlen(text);
    sprintf(&(text[offset]), "%d,", i);
}

正如其他 stackoverflow 用户所建议的那样,您也可以使用 snprintf,它还可以为您提供缓冲区溢出保护。

附加函数可能如下所示:

void append(char *text, int maxSize, char *toAppend) {
  size_t offset = strlen(text);
  snprintf(&(text[offset]), maxSize, "%s", toAppend);
}  

【讨论】:

  • 在示例中这是正确的,但是如果您将缓冲区传递给附加一些文本的函数?
  • 公平点,至少需要一个strlen() 调用才能找到buffer end。
【解决方案3】:

如果您使用的是与 POSIX 兼容的系统,请查看 fmemopen(3)open_memstream(3)

#include <assert.h>
#include <stdio.h>

int main(void)
{
    char buf[128] = { 0 };
    FILE *fp = fmemopen(buf, sizeof(buf), "w");

    assert(fp);

    fprintf(fp, "Hello World!\n");
    fprintf(fp, "%s also work, of course.\n", "Format specifiers");
    fclose(fp);

    puts(buf);
}

【讨论】:

  • 是的,与我的问题有关。但我想只使用 sprintf 来做到这一点。确实你的方式也很好,所以 +1
  • @JeegarPatel 我很好奇,是什么阻止了你使用 fprintf?它们具有完全相同的界面。
  • fmemopen 由 POSIX 定义,而不是由 C 标准定义。
猜你喜欢
  • 2011-02-10
  • 2020-06-16
  • 1970-01-01
  • 2019-08-09
  • 2015-05-31
  • 2019-10-20
相关资源
最近更新 更多