Ir ao conteúdo
  • Cadastre-se

C concatenar 3 strings usando ponteiros


Posts recomendados

Escreva uma função strcat, na linguagem C, que recebe como parâmetro 3 strings: s1, s2, e sres. A função deve retornar em sres a concatenção de s1 e s2. Obs: O usuário desta função deve tomar cuidado para declarar sres com espaço suficiente para armazenar a concatenação de s1 e s2!(FIZ USANDO 2 STRINGS)

void concatenar(char s1[], char s2[]) {
    int i, j;

    i = strlen(s1);

    for (j = 0; s2[j] != 0; i++, j++) {
        s1[i] = s2[j];
    }

    s1[i] = 0;
}

 

Link para o comentário
Compartilhar em outros sites

@paulo luz magalhaes Não entendi o seu problema :( 

 

Use nomes mais expressivos, s1 e s2? O que é o que? E a função de que precisa? 

 

Precisa de algo assim

 

    char* strcat ( const char* s1, const char* s2, char* sres );

 

mas nesse caso está claro que s1 e s2 são as partes e sres o resultado.... Retorne o endereço de sres para poder usar a função em uma expressão. É mais prático. 

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

#include<stdio.h>

#include<string.h> 



void concatenar(char *s1, char *s2) {

       while (*s1)

           s1++;

      while (*s2) {

          *s1 = *s2;

           s2++;

      s1++;

      }

*s1 = '\0';

}

O programa seria aqui que eu queria mostrar. Agora pra retornar na função SRES é que eu fico boiando como farei...

Link para o comentário
Compartilhar em outros sites

3 horas atrás, paulo luz magalhaes disse:

Escreva uma função strcat, na linguagem C

 

É essa função que tem que escrever...

 

Use como eu te mostrei.

 

Como está garantido que o cara que chama é que tem que se preocupar com o tamanho:

 

3 horas atrás, paulo luz magalhaes disse:

O usuário desta função deve tomar cuidado para declarar sres com espaço suficiente para armazenar a concatenação de s1 e s2

 

Na função não tem que fazer quase nada. Apenas copia s1 até o fim, depois copia s2 até o fim, depois coloca um zero em sres e retorna....

 

E na hora de chamar se preocupe em chamar com um lugar para sres que tenha espaço suficiente para caber s1 e s2

 

 

Link para o comentário
Compartilhar em outros sites

@paulo luz magalhaes Sua função deve ter os três parâmetros e se for void, em main é só imprimir a string passada como argumento para sres.

 

Protótipo da função,

void concatenar(char *s1, char *s2, char *sres)

 

Aí atribua e incremente os ponteiros, p.ex para s1,

while(*s1){
    *sres = *s1;
    sres += 1;
    s1 += 1;
}

 

O mesmo para o loop s2 e depois é só atribuir o caractere 0 para sres.

Link para o comentário
Compartilhar em outros sites

15 horas atrás, paulo luz magalhaes disse:

uma função strcat, na linguagem C, que recebe como parâmetro 3 strings: s1, s2, e sres. A função deve retornar em sres a concatenção de s1 e s2. Obs: O usuário desta função deve tomar cuidado para declarar sres com espaço suficiente para armazenar a concatenação de s1 e s2

 

Porque a função strcat() que está descrita no enunciado, não pode se chamar strcat, que é o que está no enunciado e é o nome dessa função em todo o planeta, uma "abreviatura" de string concat?

 

O "cuidado" do usuário é o seu mesmo ao chamar a função. Entenda que isso é uma dica do enunciado para você garantir que o destino tem o tamanho suficiente para a string resultante.

 

Sei que eu já escrevi isso mas faça o simples e declare
 

     char* strcat ( const char* s1, const char* s2, char* sres );

 

e retorne o endereço de sres porque é mais prático e esperto. 

Praticamente toda função de string.h faz isso, então não é o caso de eu ou algum de nós ser esperto, apenas a gente fazer como os caras (muito espertos) que escreveram isso, como Ken, Brian, Dennis e outros de Bell Labs, fizeram antes de nós, quando escreveram essas coisas inicialmente.

 

Eis o protótipo de strcat() oficial por exemplo

 

    char *strcat(char *destination, const char *source)

 

 

E porque alguém faria isso?

 

Simples. Para poder usar numa expressão. Funções são escritas para isso, para compor coisas. void não compõe nada. Evite void sempre.

Link para o comentário
Compartilhar em outros sites

 

18 horas atrás, paulo luz magalhaes disse:

(FIZ USANDO 2 STRINGS)

Eu também, e outros! E quando precisamos de 3 'strings' e tantas outras, chamamos a mesma função outra vez, mas com uma condição; o destino da primeira chamada [ou resultado] é também o destino na segunda chamada, e de tantas outras, sucessivamente.

 

Sugestão.: Tente a solução que retiliza aquele código do primeiro post, é igualmente fácil de fazer.

 

Exemplo:

A usar tua void concatenar () com algumas mudanças de estilo, fica assim:

char * strscat (char sres [], const char s1 [], const char s2 []) {
    
     concatenar_em (sres, s1); /* primeira concatenar */
     concatenar_em (sres, s2); /* segunda concatenar */
     
     return sres;
}

 

Estilística.: para evitar conflito, não reutilize nomes que há em palavras reservadas ou na biblioteca padrão. Quando identificar tuas funções tente ser descritivo, de nomes curtos e criativo. Se lhe falta criatividade dê nome semelhante, sem ser o mesmo, por exemplo: str_cat ().

 

Link para o comentário
Compartilhar em outros sites

Do enunciado:
 

20 horas atrás, paulo luz magalhaes disse:

Escreva uma função strcat

 

1 hora atrás, mauro_b disse:

Estilística.: para evitar conflito, não reutilize nomes que há em palavras reservadas ou na biblioteca padrão

 

Estilo a parte. o enunciado é até claro (!) no sentido de que a ideia é (re-) escrever a popular strcat() sempre presente em string.h. É um exercício comum reescrever funções de biblioteca, como strcat(), strcpy(), strlen(), strpos() e outras.

O objetivo é exatamente reescrever. Não se trata de evitar conflito.
 

20 horas atrás, paulo luz magalhaes disse:

O usuário desta função deve tomar cuidado para declarar sres com espaço suficiente para armazenar a concatenação de s1 e s2!(FIZ USANDO 2 STRINGS)

1 hora atrás, mauro_b disse:

Eu também, e outros!

 

Concatenar strings pode ser visto como somar strings. Em java por exemplo  se pode escrever 
 

         String sres = "Clube do " + "Hardware";

 

Em C++ isso pode ser feito igualzinho, usando '+' ou qualquer um de uns outros 30 operadores conhecidos, binários ou unários.

 

Porque estou escrevendo isso?

 

Simples: se s1, s2 e sres fossem int talvez ninguém fosse escrever:
 

int s1 = 2;
int s2 = 300;
int sres = 0;

// e a soma?
    sres = s1;
    sres = sres + s2;

// ou o simples
    sres = s21 + s2;

 

mas usar

 

char * strscat (char sres [], const char s1 [], const char s2 []) {
    
     concatenar_em (sres, s1); /* primeira concatenar */
     concatenar_em (sres, s2); /* segunda concatenar */
     
     return sres;
}

 

implica em criar uma outra função e fazer duas chamadas de função, empilhando 3 argumentos para cada chamada, para fazer o que é um par de simples loops. 

 

Deve levar algo como outra ordem de magnitude a mais (no popular, 10 vezes mais). E gerar muito mais código.

 

O comum, usando while e um pouco verboso

mais ou menos como @Midori sugeriu ...
 

char* strcat2(const char* s1,const char* s2, char* sres)
{
    char* pOut = (char*) sres;
    const char* pIn = s1;
    while ( *pIn != 0) { *pOut++ = *pIn++; };
    pIn = s2;
    while ( *pIn != 0) { *pOut++ = *pIn++; };
    *pOut = 0;
    return sres;
};

 

O normal, usando dois for

 

char* strcat1(const char* s1,const char* s2, char* sres)
{
    char* pOut = sres; // ponteiro para a saida
    for ( const char* pIn = s1; *pIn; *pOut = *pIn++, ++pOut );
    for ( const char* pIn = s2; *pIn; *pOut = *pIn++, ++pOut );
    *pOut = 0;
    return sres;
};

 

Um programa de teste 

 

#include <stdio.h>

char* strcat1(const char*,const char*,char*);
char* strcat2(const char*,const char*,char*);

int main(void)
{
    const char* uma = "Clube do";
    const char* outra = " Hardware";

    char soma[128];

    printf( "\t[1]\t\"%s\" + \"%s\" = \"%s\"\n",
        uma, outra, strcat1(uma, outra, soma)
    );

    soma[0] = 0; // zera saida para o proximo teste :) 

    printf( "\t[2]\t\"%s\" + \"%s\" = \"%s\"\n",
        uma, outra, strcat2(uma, outra, soma)
    );
    return 0;
}

 

E nessa expressão fica claro porque é legal retornar o endereço de sres, como eu disse inicialmente...
 

    printf( "\t[2]\t\"%s\" + \"%s\" = \"%s\"\n",
        uma, outra, strcat2(uma, outra, soma)
    );

 

É claro que escrever programas é algo criativo, mas na prática mal se consegue escrever a linguagem que vai usar, os nomes das variáveis, o número de colunas por linha, o tamanho máximo para uma função e coisas assim num mundo onde todo lugar tem um guia de normas e práticas de tudo. E nesse mundo em geral se espera uma construção como a que usa os dois for, e uma que chame duas vezes uma função para fazer a mesma coisa provavelmente não passaria por nenhuma revisão de código...

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

O programa ficou desse jeito aqui.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


void concatenar(char *s1, char *s2, char *sres){

     while(*s1){
        *sres = *s1;
         sres += 1;
         s1 += 1;
     }

     while(*s2){
        *sres = *s2;
         sres += 1;
         s2 += 1;
     }

     *sres = '\0';

}

int main()
{
    char t1[10] = "Ola";
    char t2[10] = "Teste";
    char *t3 = (char*) malloc(((int)strlen(t1) + (int)strlen(t2)+1)*sizeof(char));  
    concatenar(t1,t2,t3);
    printf("%s", t3);
    return 0;
}

 

Link para o comentário
Compartilhar em outros sites

 

4 horas atrás, arfneto disse:

Estilo a parte. o enunciado é até claro (!) no sentido de que a ideia é (re-) escrever a popular strcat() sempre presente em string.h. É um exercício comum reescrever funções de biblioteca, como strcat(), strcpy(), strlen(), strpos() e outras.

O objetivo é exatamente reescrever. Não se trata de evitar conflito.

 Reparei no teu "sentido",  já havia notada sua opinião nos postes anteriores, então não há razão de se repetir e com argumentos semelhantes, visto que é essa é a sua opinião, E não sinto em discorda quando juga necessário a solução com nome strcat, muito bobeira, quando no momento interessa o procedimento.

 

Por essa razão é enunciado: "uma função strcat", e por nenhuma outra.

 

Isto

"Escreva uma função strcat, na linguagem C, que recebe como parâmetro 3 strings: s1, s2, e sres"

 

Interpreta-se

"Escreva uma função de concatenação, na linguagem C, que recebe como parâmetro 3 'strings': s1, s2, e sres."

 

O objetivo não é reescrever strcat ou coisa alguma, porém, é escrever uma função de concatenação com 3 parâmetros, só isso.

 

4 horas atrás, arfneto disse:

Concatenar strings pode ser visto como somar strings. Em java por exemplo  se pode escrever 

Não precisa "ser visto" como, ou como dizem "interpretado", pois é o que é, e ponto final! Quem duvidar que pegue o dicionário e procure o verbo "Concatenar" e derivados na computação que a conclusão é simples de entender sem mais explicação: 

 

Citação

Concatenação: é um termo usado em computação para designar a operação de unir o conteúdo de duas strings

 

Aproposito, somar 'strings' não deixa a definição mais didático, mesmo se fosse python: onde o operador de concatenação e adição coincidem. Não é um bom exemplo enquanto se aprende C, e diferente de soma [ou adição] de números, o resultado de uma concatenação é uma sequência lógica de seus termos, e não "pode ser visto como" somar. 

 

 

4 horas atrás, arfneto disse:

implica em criar uma outra função e fazer duas chamadas de função, empilhando 3 argumentos para cada chamada, para fazer o que é um par de simples loops. 

 O enunciado não pede explicitamente que implemente somente uma função, nem ao menos é didático para chegar a essa conclusão.

 

Só repetir a mesma lógica de strcat a depender do número de parâmetros, e reutilizar essa solução para um número maior de argumentos, isso é tão coeso quanto "um par de simples loops" simbolizando strcat cada um. Mais um motivo para citar strcat. Não resta dúvida que essa é uma boa prática.

 

4 horas atrás, arfneto disse:

É claro que escrever programas é algo criativo, mas na prática mal se consegue escrever a linguagem que vai usar, os nomes das variáveis, o número de colunas por linha, o tamanho máximo para uma função e coisas assim num mundo onde todo lugar tem um guia de normas e práticas de tudo. E nesse mundo em geral se espera uma construção como a que usa os dois for, e uma que chame duas vezes uma função para fazer a mesma coisa provavelmente não passaria por nenhuma revisão de código...

Isso está mais para uma recomendação futura de adaptação simples quando é necessário. Cada qual desenvolve seu estilo pessoal que muitas vezes é resultado da experiência de muitos trabalhos em muitos empregadores. que não tem relevância agora e não precisa pensar nisso. Importante nesse momento de aprendizagem é escrever no estilo escolhido e pessoal onde se gosta mais do que vê, e deixar essas preocupações futuras quando for necessário porque não representam desafio para ninguém. 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

2 horas atrás, paulo luz magalhaes disse:

O programa ficou desse jeito aqui.





#include <stdio.h>
#include <string.h>
#include <stdlib.h>


void concatenar(char *s1, char *s2, char *sres){

     while(*s1){
        *sres = *s1;
         sres += 1;
         s1 += 1;
     }

     while(*s2){
        *sres = *s2;
         sres += 1;
         s2 += 1;
     }

     *sres = '\0';

}

int main()
{
    char t1[10] = "Ola";
    char t2[10] = "Teste";
    char *t3 = (char*) malloc(((int)strlen(t1) + (int)strlen(t2)+1)*sizeof(char));  
    concatenar(t1,t2,t3);
    printf("%s", t3);
    return 0;
}

 

 

O enunciado pede é uma função de concatenação com 3 parâmetros, OK. Só observei que está diferente em estilo se comparado a sua introdução com a void concatenar de 2 parâmetros que a propósito; usa notação de vetores e tem a mesma lógica.

  

Link para o comentário
Compartilhar em outros sites

@paulo luz magalhaes Imagino que tenha lido o que eu escrevi e as funções que eu mostrei. De todo modo seu programa está bem melhor que o programa original que postou.

 

Algumas coisas que talvez deva considerar

 

    char *t3 = (char*) malloc(((int)strlen(t1) + (int)strlen(t2)+1)*sizeof(char));  

 

  • Não sei se isso vale nota e não sou eu que vou corrigir, mas entenda que se está escrevendo outra strcat() provavelmente não pode usar nada de <string.h>  e isso quer dizer que não poderia usar strlen() nesse exercício.
  • use nomes mais significativos. É melhor. Para você inclusive. Nem todos seus programas vão ser assim pequenos
  • usar malloc() implica em usar free(). Sempre libere todo o espaço alocado.
  • Eu expliquei 2X isso e mostrei o exemplo, mas como resumo entenda que ao declarar
        void concatenar(char *s1, char *s2, char *sres);

    precisa escrever
     
        concatenar(t1,t2,t3);
        printf("%s", t3);

    mas se retornasse o endereço de sres, como fazer strcat() e todas as irmãs de string.h poderia  escrever
     
      printf("%s", concatenar(t1,t2,t3) );
// ou 
	char* p =  concatenar(t1,t2,t3);


e muitas vezes isso é vantagem.

 

  • Do modo como escreveu sua função está destruindo sua cópia de sres, o endereço de início da string. Pode ser que tenha escrito assim de propósito assumindo que não vai mais usar, mas pode ser que não tenha percebido. Em geral não se escreve assim e se preserva o ponteiro, como nos exemplos que te mostrei. Na verdade em geral por uma questão prática se retorna o mesmo ponteiro, pela mesma razão que fgets() faz isso...

 

 

 

1 minuto atrás, arfneto disse:

malloc(((int)strlen(t1) + (int)strlen(t2)+1)*sizeof(char)

 

Ainda sobre isso. tem uma coisa que acho que deve alterar se isso vale nota:

 

o parâmetro de malloc() é do tipo size_t --- no popular em geral um inteiro longo sem sinal. Está na documentação. Não é um int, mas não teria problema se fosse. 

 

Só que strlen() também retorna um size_t e aí não faz sentido o que você escreveu: converteu 2 size_t para int para depois serem convertidos para size_t de novo ??

 

E a multiplicação (opcional porque nesse caso está multiplicando por 1) deve ser pela soma dos tamanhos. Se usar isso numa máquina em que o char ocupe dois bytes por exemplo vai cancelar seu programa.

 

Deve escrever em malloc() o total de unidades a alocar * o tamanho de cada uma...

 

Note que o operador sizeof() retorna.... size_t também. Então deve escrever
 

    char* t3 = malloc( (1 + strlen(t1) + strlen(t2)) * sizeof(char) );

 

Considerando que se o char ocupar mais de um byte o terminador da string também vai...

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

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...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!