如何使用 sprintf 追加字符串?

我面临着一个严重的问题与 sprintf

假设我的代码片段是:

sprintf(Buffer,"Hello World");
sprintf(Buffer,"Good Morning");
sprintf(Buffer,"Good Afternoon");
.
.
.

几百次冲刺..。

如果我喜欢这个,就会被覆盖。

如何避免使用 sprintf覆盖?如果我给一个 printf在最后,我想看到所有的线。

192510 次浏览

You need:

sprintf(Buffer,"Hello World");
sprintf(Buffer + strlen(Buffer),"Good Morning");
sprintf(Buffer + strlen(Buffer),"Good Afternoon");

and of course you need your buffer to be big enough.

int length = 0;
length += sprintf(Buffer+length, "Hello World");
length += sprintf(Buffer+length, "Good Morning");
length += sprintf(Buffer+length, "Good Afternoon");

Here is a version with some resistance to errors. It is useful if you do not care when errors happen so long as you can continue along your merry way when they do.

int bytes_added( int result_of_sprintf )
{
return (result_of_sprintf > 0) ? result_of_sprintf : 0;
}


int length = 0;
length += bytes_added(sprintf(Buffer+length, "Hello World"));
length += bytes_added(sprintf(Buffer+length, "Good Morning"));
length += bytes_added(sprintf(Buffer+length, "Good Afternoon"));

Why do you want to use sprintf for string concatenation when there are methods intended specifically for what you need such as strcat and strncat?

What about:

char s[100] = "";


sprintf(s, "%s%s", s, "s1");


sprintf(s, "%s%s", s, "s2");


sprintf(s, "%s%s", s, "s3");


printf("%s", s);

But take into account possible buffer ovewflows!

For safety (buffer overflow) I recommend to use snprintf()

const int MAX_BUF = 1000;
char* Buffer = malloc(MAX_BUF);


int length = 0;
length += snprintf(Buffer+length, MAX_BUF-length, "Hello World");
length += snprintf(Buffer+length, MAX_BUF-length, "Good Morning");
length += snprintf(Buffer+length, MAX_BUF-length, "Good Afternoon");

Are you simply appending string literals? Or are you going to be appending various data types (ints, floats, etc.)?

It might be easier to abstract this out into its own function (the following assumes C99):

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


int appendToStr(char *target, size_t targetSize, const char * restrict format, ...)
{
va_list args;
char temp[targetSize];
int result;


va_start(args, format);
result = vsnprintf(temp, targetSize, format, args);
if (result != EOF)
{
if (strlen(temp) + strlen(target) > targetSize)
{
fprintf(stderr, "appendToStr: target buffer not large enough to hold additional string");
return 0;
}
strcat(target, temp);
}
va_end(args);
return result;
}

And you would use it like so:

char target[100] = {0};
...
appendToStr(target, sizeof target, "%s %d %f\n", "This is a test", 42, 3.14159);
appendToStr(target, sizeof target, "blah blah blah");

etc.

The function returns the value from vsprintf, which in most implementations is the number of bytes written to the destination. There are a few holes in this implementation, but it should give you some ideas.

A snprintfcat() wrapper for snprintf():

size_t
snprintfcat(
char* buf,
size_t bufSize,
char const* fmt,
...)
{
size_t result;
va_list args;
size_t len = strnlen( buf, bufSize);


va_start( args, fmt);
result = vsnprintf( buf + len, bufSize - len, fmt, args);
va_end( args);


return result + len;
}

I find the following method works nicely.

sprintf(Buffer,"Hello World");
sprintf(&Buffer[strlen(Buffer)],"Good Morning");
sprintf(&Buffer[strlen(Buffer)],"Good Afternoon");

You can use the simple line shown below to append strings in one buffer:

sprintf(Buffer,"%s %s %s","Hello World","Good Morning","Good Afternoon");

I think you are looking for fmemopen(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);
return 0;
}

If dynamic storage is more suitable for you use-case you could follow Liam's excellent suggestion about using open_memstream(3):

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


int main(void)
{
char *buf;
size_t size;
FILE *fp = open_memstream(&buf, &size);


assert(fp);


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


puts(buf);
free(buf);
return 0;
}

Use the return value of sprintf()

Buffer += sprintf(Buffer,"Hello World");
Buffer += sprintf(Buffer,"Good Morning");
Buffer += sprintf(Buffer,"Good Afternoon");

Use strcat http://www.cplusplus.com/reference/cstring/strcat/

int main ()
{
char str[80];
strcpy (str,"these ");
strcat (str,"strings ");
strcat (str,"are ");
strcat (str,"concatenated.");
puts (str);
return 0;
}








Output:




these strings are concatenated.

Using strcat(buffer,"Your new string...here"), as an option.

I write a function support dynamic variable string append, like PHP str append: str . str . ... etc.

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


int str_append(char **json, const char *format, ...)
{
char *str = NULL;
char *old_json = NULL, *new_json = NULL;


va_list arg_ptr;
va_start(arg_ptr, format);
vasprintf(&str, format, arg_ptr);


// save old json
asprintf(&old_json, "%s", (*json == NULL ? "" : *json));


// calloc new json memory
new_json = (char *)calloc(strlen(old_json) + strlen(str) + 1, sizeof(char));


strcat(new_json, old_json);
strcat(new_json, str);


if (*json) free(*json);
*json = new_json;


free(old_json);
free(str);


return 0;
}


int main(int argc, char *argv[])
{
char *json = NULL;


/*
str_append(&json, "name: %d, %d, %d", 1, 2, 3);
str_append(&json, "sex: %s", "male");
str_append(&json, "end");
str_append(&json, "");
str_append(&json, "{\"ret\":true}");
*/


int i;
for (i = 0; i < 100; i++) {
str_append(&json, "id-%d", i);
}


printf("%s\n", json);


if (json) free(json);


return 0;
}

Small full code example

Using flat plain stdio standard library only

#include <stdio.h>
int main()
{
char c[1024];
int  i=0;


i+=sprintf(c+i,"We "   );
i+=sprintf(c+i,"Love " );
sprintf(c+i,"Coding");


printf("%s",c);
}

OUTPUT: We Love Coding

char string1[] = "test";
char string2[] = "string";
int len = sizeof(string1) + sizeof(string2);
char totalString[len];
sprintf(totalString, "%s%s",string1,string2);