leer - sprintf c
¿Cómo agregar cadenas usando sprintf? (15)
¿Por qué quiere usar sprintf
para la concatenación de cadenas cuando hay métodos destinados específicamente a lo que necesita, como strcat
y strncat
?
Estoy enfrentando un problema serio con sprintf.
Supongamos que mi fragmento de código es:
sprintf(Buffer,"Hello World");
sprintf(Buffer,"Good Morning");
sprintf(Buffer,"Good Afternoon");
.
.
.
Unos cientos de sprints ...
Si me gusta esto, se sobrescribe.
¿Cómo puedo evitar sobrescribir usando sprintf? Si doy un printf al final, quiero ver todas las líneas.
¿Simplemente anexas cadenas literales? ¿O agregará varios tipos de datos (entradas, flotantes, etc.)?
Puede ser más fácil abstraer esto en su propia función (lo siguiente asume 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;
}
Y lo usarías así:
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.
La función devuelve el valor de vsprintf
, que en la mayoría de las implementaciones es el número de bytes escritos en el destino. Hay algunos agujeros en esta implementación, pero debería darle algunas ideas.
Creo que el siguiente método funciona muy bien.
sprintf(Buffer,"Hello World");
sprintf(&Buffer[strlen[Buffer]],"Good Morning");
sprintf(&Buffer[strlen[Buffer]],"Good Afternoon");
Creo que estás buscando 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;
}
Si el almacenamiento dinámico es más adecuado para su caso de uso, puede seguir la excelente sugerencia de Liam sobre el uso de 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;
}
Escribo un apéndice de cadena de variable dinámica de soporte de función, como PHP append add: 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;
}
Necesitas:
sprintf(Buffer,"Hello World");
sprintf(Buffer + strlen(Buffer),"Good Morning");
sprintf(Buffer + strlen(Buffer),"Good Afternoon");
y por supuesto necesitas que tu buffer sea lo suficientemente grande.
PEQUEÑO CÓDIGO COMPLETO EJEMPLO
Solo con la biblioteca estándar de plano plano stdio
(y no se preocupe por la caída del tamaño del vector char desde los "límites" de sprintf , cool hun? !!):
#include <stdio.h>
char c[]="";
int main()
{
int i=0;
i+=sprintf(c+i,"Sergio ");
i+=sprintf(c+i,"Mcfly ");
i+=sprintf(c+i,"NY-USA ");
i+=sprintf(c+i,"bla bla blahh...455453853;-)");
printf("%s",c);
}
PRODUCTO: Sergio Mcfly NY-USA bla bla blahh ... 455453853 ;-)
Por seguridad (desbordamiento de búfer) recomiendo usar 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");
Puede usar la línea simple que se muestra a continuación para agregar cadenas en un búfer:
sprintf(Buffer,"%s %s %s","Hello World","Good Morning","Good Afternoon");
Qué pasa:
char s[100] = "";
sprintf(s, "%s%s", s, "s1");
sprintf(s, "%s%s", s, "s2");
sprintf(s, "%s%s", s, "s3");
printf("%s", s);
¡Pero tenga en cuenta posibles sobrehornos de buffer!
Un contenedor snprintf()
para 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;
}
Usando strcat ( buffer
, " Your new string...here
"), como una opción.
Use el valor de retorno de sprintf()
Buffer += sprintf(Buffer,"Hello World");
Buffer += sprintf(Buffer,"Good Morning");
Buffer += sprintf(Buffer,"Good Afternoon");
Utilice 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.
int length = 0;
length += sprintf(Buffer+length, "Hello World");
length += sprintf(Buffer+length, "Good Morning");
length += sprintf(Buffer+length, "Good Afternoon");
Aquí hay una versión con cierta resistencia a los errores. Es útil si no te importa cuando ocurren errores, siempre y cuando puedas continuar a lo largo de tu camino feliz cuando lo hagan.
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"));