Estou trabalhando em C e preciso concatenar algumas coisas.
Agora eu tenho isso:
message = strcat("TEXT ", var);
message2 = strcat(strcat("TEXT ", foo), strcat(" TEXT ", bar));
Agora, se você tem experiência em C, tenho certeza de que você percebe que isso gera uma falha de segmentação ao tentar executá-lo. Então, como faço para resolver isso?
c
string
concatenation
The.Anti.9
fonte
fonte
Respostas:
Em C, "strings" são apenas
char
matrizes simples . Portanto, você não pode concatená-los diretamente com outras "strings".Você pode usar a
strcat
função, que anexa a string apontada porsrc
até o final da string apontada pordest
:Aqui está um exemplo de cplusplus.com :
Para o primeiro parâmetro, você precisa fornecer o próprio buffer de destino. O buffer de destino deve ser um buffer de matriz de caracteres. Por exemplo:
char buffer[1024];
Verifique se o primeiro parâmetro possui espaço suficiente para armazenar o que você está tentando copiar nele. Se disponível, é mais seguro usar funções como:
strcpy_s
estrcat_s
onde você precisa explicitamente especificar o tamanho do buffer de destino.Nota : Um literal de cadeia não pode ser usado como um buffer, pois é uma constante. Portanto, você sempre precisa alocar uma matriz de caracteres para o buffer.
O valor de retorno de
strcat
pode simplesmente ser ignorado; ele simplesmente retorna o mesmo ponteiro que foi passado como o primeiro argumento. Ele existe por conveniência e permite encadear as chamadas em uma linha de código:Portanto, seu problema pode ser resolvido da seguinte maneira:
fonte
Evite usar
strcat
no código C. A maneira mais limpa e, mais importante, a mais segura é usarsnprintf
:Alguns comentaristas levantaram uma questão de que o número de argumentos pode não corresponder à string de formato e o código ainda será compilado, mas a maioria dos compiladores já emitirá um aviso, se for o caso.
fonte
snprintf()
é um GRANDE não, não.sizeof(x)
esizeof x
. A notação entre parênteses sempre funciona e a notação não-parênteses funciona apenas às vezes; portanto, sempre use a notação entre parênteses; é uma regra simples de lembrar e é segura. Isso entra em um argumento religioso - eu estive envolvido em discussões com aqueles que objetaram antes - mas a simplicidade de 'sempre usar parênteses' supera qualquer mérito de não usá-los (IMNSHO, é claro). Isso é apresentado para o equilíbrio.Pessoal, use str n cpy (), str n cat () ou s n printf ().
Exceder o espaço no buffer será uma lixeira no que mais se seguir na memória!
(E lembre-se de permitir espaço para o caractere nulo '\ 0' à direita!)
fonte
strncpy()
. É não uma versão "mais seguro" dostrcpy()
. A matriz de caracteres de destino pode ser preenchida desnecessariamente com'\0'
caracteres extras ou, pior ainda, pode ser deixada sem terminação (ou seja, não é uma string). (Ele foi projetado para uso com uma estrutura de dados que raramente mais usado, uma matriz de caracteres acolchoada para o final com zero ou mais'\0'
caracteres.)Strings também podem ser concatenadas em tempo de compilação.
fonte
Também malloc e realloc são úteis se você não souber antecipadamente quantas seqüências de caracteres estão sendo concatenadas.
fonte
num_words>INT_MAX
, talvez você deve usarsize_t
parai
Não esqueça de inicializar o buffer de saída. O primeiro argumento para strcat deve ser uma sequência terminada nula com espaço extra suficiente alocado para a sequência resultante:
fonte
Como as pessoas apontaram, o manuseio de cordas melhorou muito. Portanto, você pode aprender como usar a biblioteca de strings C ++ em vez de strings no estilo C. No entanto, aqui está uma solução em C puro
Não tenho certeza se está correto / seguro, mas no momento não consegui encontrar uma maneira melhor de fazer isso no ANSI C.
fonte
<string.h>
é o estilo C ++. Você quer"string.h"
. Você também calculastrlen(s1)
duas vezes, o que não é necessário.s3
deve sertotalLenght+1
longo."string.h"
é um absurdo.#include <string.h>
está correto C. Use colchetes angulares para cabeçalhos padrão e do sistema (incluindo<string.h>
), aspas para cabeçalhos que fazem parte do seu programa. (#include "string.h"
Vai acontecer com o trabalho se você não tiver seu próprio arquivo de cabeçalho com esse nome, mas o uso<string.h>
de qualquer maneira.)Não é um comportamento indefinido tentar modificar literais de strings, que é algo como:
tentará fazer. Ele tentará aderir à
name
string no final da literal da string"Hello, "
, que não está bem definida.Tente algo assim. Consegue o que você parece estar tentando fazer:
Isto cria uma zona tampão que é permitido ser modificado e, em seguida, cópias tanto a cadeia literal e outro texto. Apenas tenha cuidado com estouros de buffer. Se você controlar os dados de entrada (ou verificar antes), é bom usar buffers de comprimento fixo como eu.
Caso contrário, você deve usar estratégias de mitigação, como alocar memória suficiente do heap para garantir que você possa lidar com isso. Em outras palavras, algo como:
fonte
O primeiro argumento de strcat () precisa ser capaz de manter espaço suficiente para a sequência concatenada. Portanto, aloque um buffer com espaço suficiente para receber o resultado.
strcat () concatenará o segundo argumento com o primeiro argumento e armazenará o resultado no primeiro argumento, o caractere retornado * é simplesmente esse primeiro argumento e apenas para sua conveniência.
Você não recebe uma string alocada recentemente com o primeiro e o segundo argumento concatenados, o que eu acho que você esperava com base no seu código.
fonte
A melhor maneira de fazer isso sem ter um tamanho de buffer limitado é usando asprintf ()
fonte
char *
, nãoconst char *
. O valor de retorno precisará ser passado parafree
.asprintf
é apenas uma extensão GNU.Se você possui experiência em C, notará que as strings são apenas matrizes de caracteres onde o último caractere é um caractere nulo.
Agora isso é bastante inconveniente, pois você precisa encontrar o último caractere para acrescentar algo.
strcat
fará isso por você.Portanto, o strcat pesquisa no primeiro argumento um caractere nulo. Em seguida, substituirá isso pelo conteúdo do segundo argumento (até que termine em um nulo).
Agora vamos analisar seu código:
Aqui você está adicionando algo ao ponteiro no texto "TEXT" (o tipo de "TEXT" é const char *. Um ponteiro.).
Isso geralmente não vai funcionar. A modificação da matriz "TEXT" também não funcionará, pois geralmente é colocada em um segmento constante.
Isso pode funcionar melhor, exceto que você está novamente tentando modificar textos estáticos. O strcat não está alocando nova memória para o resultado.
Eu proporia fazer algo assim:
Leia a documentação
sprintf
para verificar suas opções.E agora um ponto importante:
Verifique se o buffer possui espaço suficiente para conter o texto E o caractere nulo. Existem algumas funções que podem ajudá-lo, por exemplo, strncat e versões especiais do printf que alocam o buffer para você. Não garantir que o tamanho do buffer leve a corrupção de memória e erros exploráveis remotamente.
fonte
"TEXT"
échar[5]
, nãoconst char*
. Decaichar*
na maioria dos contextos. Por motivos de compatibilidade com versões anteriores, os literais de sequência não sãoconst
, mas tentar modificá-los resulta em um comportamento indefinido. (Em C ++, literais de cadeia de caracteres sãoconst
.)Você pode escrever sua própria função que faz a mesma coisa,
strcat()
mas que não muda nada:Se as duas cadeias juntas tiverem mais de 1000 caracteres, ela será cortada em 1.000 caracteres. Você pode alterar o valor de
MAX_STRING_LENGTH
acordo com suas necessidades.fonte
strlen(str1) + strlen(str2)
, mas você escrevestrlen(str1) + strlen(str2) + 1
caracteres. Então você pode realmente escrever sua própria função?return buffer; free(buffer);
sizeof(char) == 1
(além disso, existem outros erros mais sutis ...) Você pode ver agora por que não precisa escrever sua própria função?free(buffer);
.free(buffer);
depoisreturn buffer;
nunca é executado, vê-lo em um depurador;) Vejo agora: sim, você tem que liberar a memória namain
funçãoSupondo que você tenha um caractere [tamanho_fixo] em vez de um caractere *, você pode usar uma única macro criativa para fazer tudo de uma vez com uma
<<cout<<like
ordem ("% s the% s \ n", \ n "," than "," printf formato de estilo "). Se você estiver trabalhando com sistemas embarcados, esse método também permitirá que você deixe de fora o malloc e a grande*printf
família de funções comosnprintf()
(Isso evita que o dietlibc se queixe de * printf também)fonte
fonte
Você está tentando copiar uma sequência para um endereço que está estaticamente alocado. Você precisa entrar em um buffer.
Especificamente:
...recorte...
destino
...recorte...
http://www.cplusplus.com/reference/clibrary/cstring/strcat.html
Há um exemplo aqui também.
fonte
Esta foi a minha solução
mas você precisa especificar quantas cordas você vai concatenar
fonte
Tente algo semelhante a este:
fonte