Ir ao conteúdo

Concatenar strings no MikroC


marioscs

Posts recomendados

Postado
 

Boa tarde pessoal, estou quebrando a cabeça com uma parte tão simples do código, espero que possam me ajudar.

 

Tenho um PIC que chamo receptor, que quando recebe via serial a palavra "BSPQ1ACD" acende uma lampada.

Tenho um outro PIC que chamo transmissor, que deve enviar esta informação para acender a lampada.

 

Este PIC transmissor vai enviar mensagens para diversos receptores, então ele precisa adicionar na mensagem o nome do receptor para o qual esta enviando a ordem.

O "nome" do receptor vai bem no meio da mensagem, neste caso "Q1" é o nome do receptor. 

Criei uma função que deveria concatenar as strings "BSP" + nome do receptor + "ACD" sendo que o nome do receptor é um parâmetro da função.

 

 

Quando executo este comando: "Transmite("BSPQ1ACD")" o receptor entende perfeitamente e a lâmpada é acessa, mas o comando "Acende(0)" não funciona.

Qual pode ser o problema?

 

Agradeço toda a ajuda

 
//mainstruct pontoAutomacao{char *nome;bool status;};struct pontoAutomacao casa[1];casa[0].nome = "Q1";casa[0].status = false;//------------------------------------------void Acende(int id){char *aux;aux = strcat("BSP", casa[id].nome);aux = strcar(aux, "ACD");Transmite(aux);}//------------------------------------------------------------------------------void Transmite(unsigned char *codigo){do{Usart_Write(*codigo);*codigo++;delay_ms(1);}while(*codigo != '\0');}//------------------------------------------------------------------------------
Postado

@marioscs

 

Tentarei lhe ajudar com base no meu conhecimento em C.

 

 

Deverá haver um espaço alocado em memória para guardar a string a ser trabalhada.

 

 

Se aquele tamanho da string que você transmite é fixo, você poderá declarar da seguinte forma:

struct pontoAutomacao{   char nome[9];   bool status;};

Agora, tentarei seguir o seu programa fielmente, apenas aplicando as devidas modificações.

 

Nesta parte onde você faz:

casa[0].nome = "Q1";

Você faria:

memcpy(casa[0].nome+3, "Q1", 2);

Dentro da sua função Acende(), você aplicaria o mesmo princípio:

aux = casa[id].nome;memcpy(casa[id].nome, "BSP", 3);memcpy(casa[id].nome+5, "ACD", 3);casa[id].nome[8] = 0;

Considerando a string neste formato: BSPQ1ACD

 

 

A ideia é essa, daria para fazer de outras formas, basta adaptar às necessidades.

 

Por exemplo, se a ideia é apenas guardar a string "Q1" dentro de nome para depois transmiti-la com o restante concatenado, você poderia declarar nome[3] no seu struct e criar uma variável comando[9] dentro de Acende() para preenchê-la e depois transmitir. Como seria declarada dentro de uma função, ela seria destruída ao sair da função (bom, em C isso acontece). Isso pouparia 6 bytes adicionais no campo nome.

 

 

Teste aí..

 

 

 

LNW

Postado

@LNW

 

Sua solução funcionou muito bem, fiz algumas adaptações e no final ficou assim:

(não havia mencionado mas tem uns colchetes para marcar inicio e fim da transmissão.

//------------------------------------------------------------------------------struct pontoAutomacao{char nome[10];bool status;};//------------------------------------------------------------------------------//mainmemcpy(casa[0].nome+4, "Q1", 2);//------------------------------------------------------------------------------void Acende(int id){char *aux;aux = casa[id].nome;memcpy(casa[id].nome, "[BSP", 4);memcpy(casa[id].nome+6, "ACD]", 4);casa[id].nome[10] = '\0';Transmite(aux);}

Continuei pesquisando pra entender o problema com o meu código e no fim era o que você havia dito:

 

 

Deverá haver um espaço alocado em memória para guardar a string a ser trabalhada.

 

Alterei o código e consegui chegar neste resultado:

//------------------------------------------------------------------------------struct pontoAutomacao{char *nome;bool status;};//------------------------------------------------------------------------------//maincasa[0].nome = "Q1";//------------------------------------------------------------------------------void Acende(int id){char *pAux;char Aux[10] = "[BSP";pAux = &Aux;strcat(pAux, casa[id].nome);strcat(pAux, "ACD]");Transmite(pAux);}

Fazendo assim eu consigo poupar os bits adicionais em "nome"; Aqui as coisas criadas dentro da função também são destruídas no termino da mesma.

O estranho é que se na função "Acende(int id)" eu trocar a ordem das duas primeiras linhas, declarando o ponteiro e depois a matriz, o código compila mas não funciona..

 

Enfim.. problemas resolvido!

Muito obrigado pela sua ajuda

Postado

Olá @marioscs

 

Muito bom.. :)

 

 

Eu tenho apenas duas observações importantes que achava importante ressaltar.

 

 

1) Tamanho alocado para a string.

 

Pelo que vi, a string então acaba tendo este formato: [bSPQ1ACD]. Ou seja, 10 chars. Faltou mais alocar mais uma posição para o terminador nulo ('\0' ou 0). Logo, Aux[11]. strcat() sempre adiciona o terminador automaticamente.

 

 

2) Ponteiro para char.

 

 

O estranho é que se na função "Acende(int id)" eu trocar a ordem das duas primeiras linhas, declarando o ponteiro e depois a matriz, o código compila mas não funciona..

 

 

No código:

char *pAux;char Aux[10] = "[BSP";pAux = &Aux;

Ali você retorna o endereço do array Aux usando o operador de referência &. Bom, em C, é boa prática de programação fazermos:

pAux = Aux;

Aqui (sem o uso do operador), é retornado um ponteiro sempre para a primeira posição do array (Aux[0]).

 

 

ou

pAux = &Aux[0];

Usando o operador e explicitando qual posição do array a ser retornada. Como queremos a primeira, fazemos como acima (poderíamos retornar outras posições também).

 

 

E, caso, quisesse, nem precisaria usar aquele pAux na sua função Acende(). Poderia passar o vetor Aux diretamente como argumento da função:

Transmite(Aux);

Em C, arrays sempre "decaem" (estou fazendo tradução livre de: decay into pointers) em ponteiros ao serem passados para uma função.

 

 

É isso, ;)

 

 

Qualquer dúvida, é só perguntar. Caso queira dar o seu tópico como resolvido, tem um botão agora no novo fórum que faz isso automaticamente. (o botão Resolvido).

 

 

 

LNW

Postado

Boa tarde @LNW

 

 

 

 Faltou mais alocar mais uma posição para o terminador nulo ('\0' ou 0). Logo, Aux[11]. strcat() sempre adiciona o terminador automaticamente.

 

Quanto testei havia deixado com 20 posições e depois reduzi para 10, já estava dando problema e nem tinha visto que era isso, obrigado.

 

 

 

pAux = &Aux[0];

Ok. Vou ficar com esta forma, acho que deixa mais claro que é um endereço que esta sendo utilizado.

 

 

 

E, caso, quisesse, nem precisaria usar aquele pAux na sua função Acende(). Poderia passar o vetor Aux diretamente como argumento da função:

 

Perfeito, funcionou.

 

Obrigado novamente pela ajuda!

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!