
El.Anti.9
Estoy trabajando en C y tengo que concatenar algunas cosas.
Ahora mismo tengo esto:
message = strcat("TEXT ", var);
message2 = strcat(strcat("TEXT ", foo), strcat(" TEXT ", bar));
Ahora, si tiene experiencia en C, estoy seguro de que se da cuenta de que esto le da una falla de segmentación cuando intenta ejecutarlo. Entonces, ¿cómo trabajo alrededor de eso?

alex b
Evitar el uso de strcat
en código C. La forma más limpia y, sobre todo, la más segura es utilizar snprintf
:
char buf[256];
snprintf(buf, sizeof(buf), "%s%s%s%s", str1, str2, str3, str4);
Algunos comentaristas plantearon el problema de que la cantidad de argumentos puede no coincidir con la cadena de formato y el código aún se compilará, pero la mayoría de los compiladores ya emiten una advertencia si este es el caso.
Las cadenas también se pueden concatenar en tiempo de compilación.
#define SCHEMA "test"
#define TABLE "data"
const char *table = SCHEMA "." TABLE ; // note no + or . or anything
const char *qry = // include comments in a string
" SELECT * " // get all fields
" FROM " SCHEMA "." TABLE /* the table */
" WHERE x = 1 " /* the filter */
;

Brian R. Bondy
En C, las “cadenas” son simplemente simples char
arreglos Por lo tanto, no puede concatenarlas directamente con otras “cadenas”.
Puedes usar el strcat
función, que añade la cadena apuntada por src
al final de la cadena apuntada por dest
:
char *strcat(char *dest, const char *src);
Aquí hay un ejemplo de cplusplus.com:
char str[80];
strcpy(str, "these ");
strcat(str, "strings ");
strcat(str, "are ");
strcat(str, "concatenated.");
Para el primer parámetro, debe proporcionar el propio búfer de destino. El búfer de destino debe ser un búfer de matriz de caracteres. P.ej: char buffer[1024];
Asegurarse que el primer parámetro tiene suficiente espacio para almacenar lo que está tratando de copiar en él. Si está disponible para usted, es más seguro usar funciones como: strcpy_s
y strcat_s
donde tiene que especificar explícitamente el tamaño del búfer de destino.
Nota: un literal de cadena no se puede usar como un búfer, ya que es una constante. Por lo tanto, siempre debe asignar una matriz de caracteres para el búfer.
El valor de retorno de strcat
simplemente se puede ignorar, simplemente devuelve el mismo puntero que se pasó como primer argumento. Está ahí para su comodidad y le permite encadenar las llamadas en una sola línea de código:
strcat(strcat(str, foo), bar);
Entonces su problema podría resolverse de la siguiente manera:
char *foo = "foo";
char *bar = "bar";
char str[80];
strcpy(str, "TEXT ");
strcat(str, foo);
strcat(str, bar);

Nico Cvitak
La mejor manera de hacerlo sin tener un tamaño de búfer limitado es usando asprintf()
char* concat(const char* str1, const char* str2)
{
char* result;
asprintf(&result, "%s%s", str1, str2);
return result;
}

ceros
Como la gente señaló, el manejo de cadenas mejoró mucho. Por lo tanto, es posible que desee aprender a usar la biblioteca de cadenas de C++ en lugar de las cadenas de estilo C. Sin embargo, aquí hay una solución en C puro.
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void appendToHello(const char *s) {
const char *const hello = "hello ";
const size_t sLength = strlen(s);
const size_t helloLength = strlen(hello);
const size_t totalLength = sLength + helloLength;
char *const strBuf = malloc(totalLength + 1);
if (strBuf == NULL) {
fprintf(stderr, "malloc failed\n");
exit(EXIT_FAILURE);
}
strcpy(strBuf, hello);
strcpy(strBuf + helloLength, s);
puts(strBuf);
free(strBuf);
}
int main (void) {
appendToHello("blah blah");
return 0;
}
No estoy seguro de si es correcto/seguro, pero en este momento no pude encontrar una mejor manera de hacerlo en ANSI C.

keith thompson
Amigos, usen strnortecpy(), cadenanortegato(), o snorteimprimirf().
¡Exceder el espacio del búfer destruirá cualquier otra cosa que siga en la memoria!
(¡Y recuerde dejar espacio para el carácter final nulo ‘\0’!)

Pedro Mortensen
Si tiene experiencia en C, notará que las cadenas son solo matrices de caracteres donde el último carácter es un carácter nulo.
Ahora eso es bastante inconveniente ya que tienes que encontrar el último carácter para agregar algo. strcat
hará eso por ti.
Así que strcat busca en el primer argumento un carácter nulo. Luego lo reemplazará con el contenido del segundo argumento (hasta que termine en nulo).
Ahora revisemos su código:
message = strcat("TEXT " + var);
Aquí está agregando algo al puntero del texto “TEXTO” (el tipo de “TEXTO” es const char*. Un puntero).
Eso generalmente no funcionará. Además, la modificación de la matriz “TEXTO” no funcionará, ya que generalmente se coloca en un segmento constante.
message2 = strcat(strcat("TEXT ", foo), strcat(" TEXT ", bar));
Eso podría funcionar mejor, excepto que nuevamente está intentando modificar textos estáticos. strcat no asigna memoria nueva para el resultado.
Yo propondría hacer algo como esto en su lugar:
sprintf(message2, "TEXT %s TEXT %s", foo, bar);
Lea la documentación de sprintf
para comprobar sus opciones.
Y ahora un punto importante:
Asegúrese de que el búfer tenga suficiente espacio para contener el texto Y el carácter nulo. Hay un par de funciones que pueden ayudarlo, por ejemplo, strncat y versiones especiales de printf que asignan el búfer por usted. No garantizar el tamaño del búfer conducirá a la corrupción de la memoria y errores explotables de forma remota.
¡Me gustaría sugerir que use strlcat en lugar de strcat! gratisoft.us/todd/papers/strlcpy.html
– activoout.se
21 de noviembre de 2008 a las 13:37
Me gustaría repetir esa sugerencia. Strcat causa vulnerabilidad a las explotaciones de desbordamiento de búfer. Alguien puede darle a su programa datos que hagan que ejecute código arbitrario.
– Brian
21 de noviembre de 2008 a las 14:10