Estoy trabajando en C, y tengo que concatenar algunas cosas.
En este momento 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 dará cuenta de que esto le da un error de segmentación cuando intenta ejecutarlo. Entonces, ¿cómo puedo solucionar eso?
c
string
concatenation
The.Anti.9
fuente
fuente
Respuestas:
En C, las "cadenas" son simplemente
char
matrices simples . Por lo tanto, no puede concatenarlos directamente con otras "cadenas".Puede usar la
strcat
función, que agrega la cadena apuntada porsrc
al final de la cadena apuntada pordest
:Aquí hay un ejemplo de cplusplus.com :
Para el primer parámetro, debe proporcionar el búfer de destino en sí. El búfer de destino debe ser un búfer de matriz de caracteres. P.ej:
char buffer[1024];
Asegúrese de que el primer parámetro tenga suficiente espacio para almacenar lo que está intentando copiar. Si está disponible para usted, es más seguro usar funciones como:
strcpy_s
ystrcat_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:Entonces su problema podría resolverse de la siguiente manera:
fuente
Evite usar
strcat
en el código C. La forma más limpia y, lo más importante, la más segura es usarsnprintf
:Algunos comentaristas plantearon un problema de que el número 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.
fuente
snprintf()
es un GRAN no no.sizeof(x)
ysizeof x
. La notación entre paréntesis siempre funciona y la notación sin paréntesis solo funciona a veces, así que siempre use la notación entre paréntesis; Es una regla simple de recordar y es segura. Esto entra en un argumento religioso: he estado involucrado en discusiones con aquellos que se oponen antes, pero la simplicidad de 'siempre usar paréntesis' supera cualquier mérito de no usarlos (IMNSHO, por supuesto). Esto se presenta para el equilibrio.Amigos, use str n cpy (), str n cat () o s n printf ().
¡Superar su espacio de búfer destruirá todo lo que sigue en la memoria!
(¡Y recuerde dejar espacio para el carácter nulo '\ 0' final!)
fuente
strncpy()
. Es no una versión "segura" destrcpy()
. La matriz de caracteres de destino puede rellenarse innecesariamente con'\0'
caracteres adicionales o, lo que es peor, puede dejarse sin terminar (es decir, no una cadena). (Fue diseñado para su uso con una estructura de datos que rara vez se utiliza más, una matriz de caracteres rellena hasta el final con cero o más'\0'
caracteres.)Las cadenas también se pueden concatenar en tiempo de compilación.
fuente
También malloc y realloc son útiles si no sabe de antemano cuántas cadenas se concatenan.
fuente
num_words>INT_MAX
, tal vez debería utilizarsize_t
parai
No olvides inicializar el búfer de salida. El primer argumento para strcat debe ser una cadena terminada en nulo con suficiente espacio extra asignado para la cadena resultante:
fuente
Como la gente señaló, el manejo de cuerdas 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
No estoy seguro de si es correcto / seguro, pero en este momento no podría encontrar una mejor manera de hacerlo en ANSI C.
fuente
<string.h>
es estilo C ++ Que desea"string.h"
. También calculastrlen(s1)
dos veces, lo que no es necesario.s3
debería sertotalLenght+1
largo"string.h"
tiene sentido.#include <string.h>
es correcto C. Use corchetes angulares para encabezados estándar y del sistema (incluidos<string.h>
), comillas para encabezados que forman parte de su programa. (#include "string.h"
funcionará si no tienes tu propio archivo de encabezado con ese nombre, pero úsalo de<string.h>
todos modos)Es un comportamiento indefinido intentar modificar los literales de cadena, que es algo así como:
intentará hacer. Intentará agregar la
name
cadena al final del literal de cadena"Hello, "
, que no está bien definido.Intenta algo así. Alcanza lo que parece estar tratando de hacer:
Esto crea un área de búfer que se puede modificar y luego copia tanto el literal de cadena como otro texto. Solo tenga cuidado con los desbordamientos del búfer. Si controla los datos de entrada (o los verifica de antemano), está bien usar buffers de longitud fija como yo.
De lo contrario, debe usar estrategias de mitigación como asignar suficiente memoria del montón para asegurarse de que puede manejarlo. En otras palabras, algo como:
fuente
El primer argumento de strcat () debe ser capaz de contener suficiente espacio para la cadena concatenada. Asigne un búfer con suficiente espacio para recibir el resultado.
strcat () concatenará el segundo argumento con el primer argumento, y almacenará el resultado en el primer argumento, el char * devuelto es simplemente este primer argumento, y solo para su conveniencia.
No obtiene una cadena recién asignada con el primer y segundo argumento concatenados, lo que supongo que esperaba en función de su código.
fuente
La mejor manera de hacerlo sin tener un tamaño de búfer limitado es mediante el uso de asprintf ()
fuente
char *
, noconst char *
. El valor de retorno deberá pasarse afree
.asprintf
es solo una extensión de GNU.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 incómodo, ya que tienes que encontrar el último personaje para agregar algo.
strcat
Hará eso por ti.Entonces strcat busca en el primer argumento un carácter nulo. Luego reemplazará esto con el contenido del segundo argumento (hasta que termine en un valor nulo).
Ahora veamos tu código:
Aquí está agregando algo al puntero al texto "TEXTO" (el tipo de "TEXTO" es const char *. Un puntero).
Eso generalmente no funcionará. La modificación de la matriz "TEXTO" tampoco funcionará, ya que generalmente se coloca en un segmento constante.
Eso podría funcionar mejor, excepto que nuevamente está intentando modificar textos estáticos. strcat no está asignando nueva memoria para el resultado.
En su lugar, propondría hacer algo como esto:
Lea la documentación de
sprintf
para verificar 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 le asignan el búfer. No garantizar que el tamaño del búfer provocará daños en la memoria y errores explotables de forma remota.
fuente
"TEXT"
eschar[5]
, noconst char*
. Se descomponechar*
en la mayoría de los contextos. Por razones de compatibilidad con versiones anteriores, los literales de cadena no lo sonconst
, pero intentar modificarlos da como resultado un comportamiento indefinido. (En C ++, los literales de cadena sonconst
.)Puede escribir su propia función que haga lo mismo
strcat()
pero que no cambie nada:Si ambas cadenas juntas tienen más de 1000 caracteres, cortará la cadena a 1000 caracteres. Puede cambiar el valor de
MAX_STRING_LENGTH
para satisfacer sus necesidades.fuente
strlen(str1) + strlen(str2)
, pero escribesstrlen(str1) + strlen(str2) + 1
caracteres. Entonces, ¿puedes realmente escribir tu propia función?return buffer; free(buffer);
sizeof(char) == 1
(además, hay otros errores más sutiles ...) ¿Puedes ver ahora por qué no tienes que escribir tu propia función?free(buffer);
.free(buffer);
despuésreturn buffer;
nunca se ejecuta, verlo en un depurador;) Ahora veo: sí, tienes que liberar la memoria en lamain
funciónSuponiendo que tiene un char [fixed_size] en lugar de un char *, puede usar una única macro creativa para hacerlo todo de una vez con un
<<cout<<like
pedido ("en lugar de% s el desarticulado% s \ n", "que", "printf formato de estilo "). Si está trabajando con sistemas integrados, este método también le permitirá omitir malloc y la gran*printf
familia de funciones comosnprintf()
(Esto evita que dietlibc también se queje de * printf)fuente
fuente
Está intentando copiar una cadena en una dirección que está asignada estáticamente. Necesitas un gato en un búfer.
Específicamente:
...recorte...
destino
...recorte...
http://www.cplusplus.com/reference/clibrary/cstring/strcat.html
Hay un ejemplo aquí también.
fuente
Esta fue mi solución
pero necesita especificar cuántas cadenas va a concatenar
fuente
Prueba algo similar a esto:
fuente