Ir ao conteúdo
  • Cadastre-se
Claudir Junior

C Encontrar palavra em uma frase e substituir por outra

Posts recomendados

Estou estudando strings e preciso fazer um algoritmo que encontre uma string A em uma frase F e substitua por uma string B (de mesmo tamanho que A).

Consegui montar um código que aparentemente funciona, mas quando coloco F como "banana banana", A como "banana" e B como "cabana", o resultado sai "cacaca cabana" (kkkkkk), não sei por quê. Saberiam me dizer onde está a falha?

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

int main(){

    char F[501], A[26], B[26];
    int a, b, l, i, j, k;

    printf("Digite uma frase de ate 500 caracteres: ");
    gets(F);
    printf("\nDigite uma palavra de ate 25 caracteres: ");
    gets(A);
    a = strlen(A);
    printf("\nDigite outra palavra, do mesmo tamanho da anterior: ");
    gets(B);
    b = strlen(B);
    if(b != a){
        do{
        printf("\nDigite outra palavra, do MESMO TAMANHO da anterior: ");
        gets(B);
        b = strlen(B);
        }while(b != a);
    }

    l = strlen(F);

    for(i = 0; i<=(l-a); i++){
        if(F[i] == A[0]){
            k = i;
            for(j = 0; j<a; j++){
                if(A[j] == F[k]){
                    F[k] = B[j];
                    k++;
                }
            }
        }
    }

    printf("\n%s\n", F);

    return 0;
}

 

  • Obrigado 1
  • Amei 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Claudir Junior    nesse codigo voce esta procurando a palavra e ao mesmo tempo fazendo a substituicao , creio que seria melhor voce procurar na frase ate encontrar a palavra e marcar a posicao do inicio dela para em seguida inserir a outra no lugar , pois se nao encontrar nao farah a substituicao . 

então seu código poderia ser assim  :

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

int main(){
    char F[501], A[26], B[26];
    int a, b, l, i, j, k,flag=1;

    printf("Digite uma frase de ate 500 caracteres: ");
    gets(F);
    do{
        printf("\nDigite uma palavra de ate 25 caracteres: ");
        gets(A);
        a = strlen(A);
    }while(a > 25);
    do{
        printf("\nDigite outra palavra, do mesmo tamanho da anterior: ");
        gets(B);
        b = strlen(B);
    }while(b != a);
    for(i = 0; F[i]!= '\0'; i++){
        if(F[i] == A[0]){
            flag=1;
            k = i;
            for(j = 0; A[j] != '\0'; j++){
                if(A[j] != F[i]){
                    flag=0;
                    printf("%c",A[j]);
                }
                i++;
            }      
        }
    }
    if( flag ){
         for(j=0;B[j] != '\0'; j++){
            F[k] = B[j];    
            k++;         
        }  
    }
    printf("\n\n%s\n\n\n", F);
    system("pause");
    return 0;
}
 

 

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites

@devair1010 se a última palavra na frase começa com as sílabas que tem a palavras A o algoritmo aplicará B. Pode visualizar isso também quando a frase é de uma só palavra.

 

Ex.: seja F: Banana, A: na, B: n4, a resposta é Ban4na.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
8 horas atrás, devair1010 disse:

@Claudir Junior    nesse codigo voce esta procurando a palavra e ao mesmo tempo fazendo a substituicao , creio que seria melhor voce procurar na frase ate encontrar a palavra e marcar a posicao do inicio dela para em seguida inserir a outra no lugar , pois se nao encontrar nao farah a substituicao . 

então seu código poderia ser assim  :


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

int main(){
    char F[501], A[26], B[26];
    int a, b, l, i, j, k,flag=1;

    printf("Digite uma frase de ate 500 caracteres: ");
    gets(F);
    do{
        printf("\nDigite uma palavra de ate 25 caracteres: ");
        gets(A);
        a = strlen(A);
    }while(a > 25);
    do{
        printf("\nDigite outra palavra, do mesmo tamanho da anterior: ");
        gets(B);
        b = strlen(B);
    }while(b != a);
    for(i = 0; F[i]!= '\0'; i++){
        if(F[i] == A[0]){
            flag=1;
            k = i;
            for(j = 0; A[j] != '\0'; j++){
                if(A[j] != F[i]){
                    flag=0;
                    printf("%c",A[j]);
                }
                i++;
            }      
        }
    }
    if( flag ){
         for(j=0;B[j] != '\0'; j++){
            F[k] = B[j];    
            k++;         
        }  
    }
    printf("\n\n%s\n\n\n", F);
    system("pause");
    return 0;
}
 

 

O que significa esse "if( flag )" no final? Desculpe a minha ignorância, sou iniciante em programação.

  • Amei 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Claudir Junior     na linguagem  c  não tem o tipo boolean , então uma forma de implementar algo parecido é usando hum int , e nesse caso a variável flag significa true ou false , true se ela tiver um valor diferente de zero , e false se o valor dela for igual a zero ,  assim esse if( flag ) significa

se flag igual a hum , ou diferente de zero .   testou o código ?   

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@devair1010 entendi. Valeu pela explicação. Eu testei o código e parece que está com o problema que o @MB_ mencionou, mesmo. Vou tentar achar a falha por aqui.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Claudir Junior     imaginei que você queria substituir apenas huma palavra da frase ,  então para substituir todas as que são iguais a palavra A pela palavra B ,  com essa modificação :

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

int main(){
    system("color ec");
    char F[501], A[26], B[26];
    int a, b, l, i, j, k,flag=1;

    printf("Digite uma frase de ate 500 caracteres: ");
    gets(F);
    do{
        printf("\nDigite uma palavra de ate 25 caracteres: ");
        gets(A);
        a = strlen(A);
    }while(a > 25);
    do{
        printf("\nDigite outra palavra, do mesmo tamanho da anterior: ");
        gets(B);
        b = strlen(B);
    }while(b != a);
    for(i = 0; F[i]!= '\0'; i++){
        if(F[i] == A[0]){
            flag=1;
            k = i;
            for(j = 0; A[j] != '\0'; j++){
                if(A[j] != F[i]){
                    flag=0;
                }
                i++;
            }  
            i--;
            if( flag ){
                for(j=0;B[j] != '\0'; j++){
                    F[k] = B[j];    
                    k++;         
                }  
            }    
        }
    }
    printf("\n\n%s\n\n\n", F);
    system("pause");
    return 0;
}
 

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

⚠️ Notei que há biblioteca string.h @Claudir Junior , e o programa está, sendo sincero, uma bela gambiarra. Poderia ter usado melhor os recursos importados e quase nada utilizados.

  • Curtir 1
  • Haha 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá!

Acho que está indo bem, mas precisa separar dois pontos:

  • estar certo de que encontrou a palavra na frase
  • depois ir até o local e trocar letra por letra.

como sempre sugiro aqui: não misture as coisas durante os testes:

  • não comece lendo valores da tela: leva uma eternidade a toa.
  • depois que estiver ok você coloca a parte da leitura em minutos
  • evite usar tantas variáveis de uma letra só juntas. Fica mais difícil para você mesmo acompanhar
  • comente o que você acha que devia estar acontecendo, direto nas linhas de código
  • atente para o enunciado: é um contrato entre você e o instrutor: procure não fazer mais, mas se garantir de que fez o mínimo. Nesse caso aqui, a frase pode ter até 500 caracteres, imagino. Então a palavra também pode ter esse tamanho: uma frase pode ser de uma palavra só.

Eis um possível roteiro comentado para escrever isso, com exemplo e o código.

Atente para esta possibilidade e para o que eu escrevi acima: não tente escrever tudo de uma vez.

 

isso aqui é só um exemplo: pode não ser nem bom ou conter erros... Mas pode ser bom e estar certinho

 

A gente precisa aqui de uma rotina assim: 

int        troca_palavra_na_frase(char* frase, char* palavra, char* palavra_nova)
{
    // ...
};
  • O tamanho máxima da frase é de 500 caracteres
  • uma frase pode ter uma palavra só e então o tamanho máximo de palavra é também 500
  • a nova palavra tem o mesmo tamanho, está escrito lá. Então o tamanho máximo da palavra nova também é 500.

Se eu rodar

    char*     frase = "azul";
    char      teste[501];    // 500 mais o null no final

    strcpy( teste, frase );
    troca_palavra_na_frase(teste, "azul", "abcd");
    printf("final: [%s]\n", teste);

No final a frase vai ficar "abcd".

 

Seguindo o plano: strstr()

 

 

Em C tem na biblioteca padrão uma rotina que em muitos lugares -- livros e sites --- aparece assim 

char *strstr(const char *haystack, const char *needle);

Exemplo

 

aqui podia ser assim

char *strstr(const char *palheiro, const char *agulha)

claro que em português se fala em encontrar a agulha no palheiro --- needle e haystack --- e em português as posições provavelmente seriam invertidas:

char *strstr(const char *agulha, const char *palheiro);

Essa rotina devolve o endereço da string agulha na string palheiro, ou zero se não acha. É quase a solução para o exercício e assim imagino que não podemos usar essa strstr(). Esse é quase o nosso objetivo afinal. 

 

Mas se a gente tivesse uma rotina dessas a nossa rotina troca_palavra_na_frase() ficaria bem simpes: strstr() devolve a posição inicial da agulha no palheiro, ou zero. Então se strstr() existisse bastaria --- se ela não voltou zero --- começar a colocar na frase o novo valor, a partir da exata posição que a rotina devolveu. Nada mais. Como elas são do mesmo tamanho, não tem que ver o 0 no final nem nada.

 

Uma possível rotina:

int        troca_palavra_na_frase(char* frase, char* palavra, char* palavra_nova)
{
    int t = strlen(palavra);
    if (t != strlen(palavra_nova)) return -2;
    if (strlen(frase) < strlen(palavra)) return -3;
    char* pos = ch_strstr(frase, palavra);        // retorna 0 ou o endereco da palavra na frase
    if (pos == 0) return -1;                    // nao tinha a palavra na frase
    for (int i = 0; i < t; i += 1)                // tinha, entao faz a troca
    {
        *(pos + i) = *(palavra_nova + i);        // retorna a posicao da troca
    }
    return (pos - frase);    // so isso
}    // end troca_palavra_na_frase()

São 5 linhas de código na verdade. Note que ela retorna

  • -1 quando não achou a palavra na frase
  • -2 quando a palavra e a palavra nova não tem o mesmo tamanho
  • -3 quando a palavra for menor que a frase
  • Ou retorna a posição da palavra na frase

E essa ch_strstr()? Era a strstr()?

Se você puder usar isso em seu exercício já terminamos: apenas troque ch_strstr() por strstr() e já estará funcionando. O header "string.h" já está declarado lá em seu programa mesmo

#include "string.h"

E essa rotina fica com a família lá, como strcpy() e strlen().

A gente não pode escrever outra strstr() assim fácil aqui, com o mesmo nome, porque elá está na biblioteca padrão junto com as outras.  E eu não queria escrever essas duas outras também... A gente escreve aqui no tempo livre afinal... E ao incluir #include "string.h" vem tudo junto.

 

Então...Criando outra strstr() 

 

Essa é a primeira consideração: veja o exemplo abaixo

    0
    XYZT
    01234567890123456789 frase com 20 caracteres
                    XYZT
                        |
                        \
                         - 16

    Na frase a palavra pode estar a partir do inicio, 0 ate a posição final em que ela cabe:

Citação

 

    Se
          t = tamanho da palavra
          n = tamanho da frase
    Então
          a palavra pode estar começando entre 0 e (n-t) inclusive, na frase

    No exemplo, XYZT tem 4 posições e a frase tem 20 então a palavra
    pode estar entre 0 e 16. Se passar de 16 = (n-t) ela não cabe

 


 Uma versão .br.ch de strstr() podia ser

char* ch_strstr(const char* Palheiro, const char* Agulha)
{
    int        n = strlen(Palheiro);
    int        t = strlen(Agulha);
    int        ultimo = n - t;
    int        matches = 0;
    
    char*    pos = 0;
    char*    posFrase =        (char*) Palheiro;
    char*    posPalavra =    (char*) Agulha;
    int        candidato = 0;
    // ja sei onde procurar: de 0 ate 'ultimo'
    for (int i = 0; i <= n; i++)
    {    
        // tem duas situações: posso estar em uma parte 
        // da string que eu procuro ou nao
        if (candidato!=0)
        {    // ja estou em um candidato
            if (*(i + posFrase) != *(posPalavra))
            {
                matches = 0;
                candidato = 0;
                posPalavra = (char*)Agulha;    // comeca de novo
            }
            else
            {
                matches = matches + 1;
                if (matches == t) return pos;
                posPalavra += 1;
            }    // end if
        }
        else
        {    // ainda buscando um inicio
            if (i > ultimo) return 0;        // nao cabe mais
            if ( *(i + posFrase) != *(posPalavra) ) continue;
            // achou a primeira letra
            candidato = 1;
            posPalavra += 1;
            pos = posFrase + i;
            matches = 1;    //    achei a primeira letra
        }    // end if

    }    // end for
    return 0;
}    // end strstr()

Preste atenção especial ao if interno ao for e vai ver algo parecido com o que está faltando em seu programa exemplo. Se não entender escreva perguntando

 

De volta à função, nada complicado. Apenas um loop nesse intervalo que definimos, procurando pela palavra na frase. Tem um if dentro porque a gente pode estar em duas situações: ou procurando o início da palavra ou vendo se ela está todinha lá a partir do início. E ela pode não estar inteira então temos que poder voltar a procurar. Esse é o código, nessa ordem.


Claro, é só um exemplo.

 

Note que ch_strstr() devolve um endereço e isso é bem conveniente. Estamos reproduzindo o comportamento da rotina strstr() porque como eu já disse, os caras que escreveram isso são bem melhores que eu...

 

Quando eu escrevo aqui eu sempre recomendo: escrever e testar aos poucos, sem ler da console ou ficar compilando. Assim, no programa de teste  tem uma rotina teste1() que faz vários testes para ch_strstr() e a gente não passa adiante até ter uma certa convicção de que ela funciona...

 

Veja o início dessa rotina de testes:

void        teste1()
{
    //
    // testes para strstr
    //
    char* Palheiro = "Palheiro";
    char* Agulha =   "Agulha";

    char teste_frase[80];
    char teste_palavra[80];
    int n;

    strcpy(teste_frase, Palheiro);

    strcpy(teste_palavra, "iro");
    n = testa_strstr(teste_frase, teste_palavra);
    printf("strstr(%s,%s) retornou %d\n", Palheiro, teste_palavra, n);

e a testa_strstr()

int        testa_strstr(char* palheiro, char* agulha)
{
    char* r = ch_strstr(palheiro, agulha);
    if (r == 0)
    {
        printf("nao achou [%s] em [%s]\n", agulha, palheiro);
    }
    else
    {
        printf("achou [%s] em [%s]!\n", agulha, palheiro);
        printf("posicao: %d\n", (r - palheiro) );
    }
    return (r != 0);
}    // end testa_strstr()

Adiante então


Supondo que a ch_ststr() funciona, então a troca_palavra_na_frase() também deve funcionar, com todas as suas 10 linhas de código. Um código de teste podia ser assim, considerando o exemplo acima. Note que os casos óbvios de ter 

a palavra XYZT

  • no começo
  • no meio
  • no fim
  • ausente
  • e o caso de a palavra ser a frase inteira

já estão cobertos no teste... Veja logo nas primeiras linhas

void        teste2()
{
    char*    palavra =            "XYZT";
    char*    palavra_nova =       "abcd";
    char*    frase =              "01234567890123456789"; // sem a palavra
    char*    frase_i =            "XYZT4567890123456789"; // palavra no inicio
    char*    frase_m =            "01234567XYZT23456789"; // palavra no meio
    char*    frase_f =            "0123456789012345XYZT"; // palavra no fim

    char teste_frase[501];
    char teste_palavra[501];
    char teste_palavra_nova[501];
    int n;


    // o exemplo inicial
    strcpy(teste_frase, "azul");
    strcpy(teste_palavra, "azul");
    strcpy(teste_palavra_nova, "abcd");

    printf("\
    troca_palavra_na_frase()\n\
    frase ..........[%s]\n\
    palavra ........[%s]\n\
    palavra nova ...[%s]\n\n",
        teste_frase,
        teste_palavra,
        teste_palavra_nova
    );

    n = troca_palavra_na_frase(teste_frase, teste_palavra, teste_palavra_nova);
    printf("    retornou %d\n\n", n);
    printf("    frase no final..[%s]\n\n\n", teste_frase);

......

O resto da rotina teste2() faz isso. E o código da saída de um teste desses está disponível junto com o programa de teste

    troca_palavra_na_frase()
    frase ..........[azul]
    palavra ........[azul]
    palavra nova ...[abcd]

    retornou 0

    frase no final..[abcd]

A saída do teste completo está aqui saída do programa de teste está aqui como exemplo
O programa de teste
Tem um botão para download em formato zip da pasta toda em https://github.com/ARFNeto-CH/ch-191006-frase


A função main() não podia ser mais simples: tem uma linha só:

  • teste1(); até estar mais ou menos seguro com a ch_strstr()
  • teste2(); para testar a rotina que troca a palavra
  • E estão preservadas lá teste1() e teste2() porque se achar um erro pode ser na primeira função e não queremos perder isso.

 

  • Curtir 4

Compartilhar este post


Link para o post
Compartilhar em outros sites

@arfneto Sabia que tu apavorava em redes mas não sabia que era craque em programas....👏

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
1 hora atrás, misterjohn disse:

@arfneto Sabia que tu apavorava em redes mas não sabia que era craque em programas....👏

menos, bem menos meu amigo! Mas escrevo também nesse forum e outros para tirar dúvidas ou conhecer algum problema mais interessante. Abraço

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites

Confirma-me uma coisa [estou revolvendo aqui também] @Claudir Junior

Em 05/10/2019 às 16:33, MB_ disse:

Ex.: seja F: Banana, A: na, B: n4, a resposta é Ban4na.

Foi a solução primeira de @devair1010

A solução de @arfneto tem o mesmo resultado.

 

Em 06/10/2019 às 01:23, Claudir Junior disse:

Eu testei o código e parece que está com o problema que o @MB_ mencionou, mesmo. Vou tentar achar a falha por aqui.

No exemplo acima a resposta deve ser Ban4n4?

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
6 horas atrás, MB_ disse:

Confirma-me uma coisa [estou revolvendo aqui também] @Claudir Junior

Foi a solução primeira de @devair1010

A solução de @arfneto tem o mesmo resultado.

 

No exemplo acima a resposta deve ser Ban4n4?

 

 

Não. O enunciado NÃO diz para substituir todas as ocorrências, então basta a primeira. E tem uma pegadinha nesse caso que eu acho que seria maldade passar para os alunos

 

Veja o enunciado:

 

Em 05/10/2019 às 03:59, Claudir Junior disse:

algoritmo que encontre uma string A em uma frase F e substitua por uma string B (de mesmo tamanho que A).

 

Por outro lado, não tem nada de especial substituir todas, se temos uma rotina

int        troca_palavra_na_frase(char* frase, char* palavra, char* palavra_nova)

que faz a troca e retorna a posição da palavra na frase ou (-1) se não achou a palavra na frase, então basta um loop para trocar todas

 

Pegadinha

 

Ao trocar todas as ocorrências é preciso adiantar a posição do ponteiro da frase para além da ocorrência substituída a cada vez na frase. Não dá pra chamar sempre com a frase completa porque podemos ter um loop infinito.

Porque? A palavra nova pode trazer novas ocorrências da palavra antiga e aí a troca nunca acaba

 

Sabendo disso, podemos escrever:

int        troca_toda_palavra_na_frase(char* frase, char* palavra, char* palavra_nova);

Que usa a rotina anterior até se esgotarem as ocorrências e retorna o número de substituições feitas na frase. Eis um código possível, imune à pegadinha:

int        troca_toda_palavra_na_frase(char* frase, char* palavra, char* palavra_nova)
{
    int n, quantos = 0;
    char* indice = frase;
    do
    {
        n = troca_palavra_na_frase(indice, palavra, palavra_nova);
        quantos += 1;
        if (n < 1) return quantos;        // acabaram as palavras na frase
        indice += n;        // adianta os indicadores
    } while (1>0);
}    // end troca_palavra_na_frase()

A linha 

indice += n;

adianta o ponteiro na frase... E fica claro porque o pessoal que escreveu strstr() tinha razão ao retornar o endereço. Tudo fica mais fácil... Caras espertos.

 

Podendo usar strstr(), a rotina em string.h

Como eu disse antes, acho que não é pra usar strstr() nesse exercício porque ficaria muito trivial. Mas não está escrito lá. Eu perguntaria ao instrutor. Na dúvida eu mostrei antes como escrever outra, ch_strstr(). Está logo acima, mas vamos supor que a gente possa usar: a rotina que troca podia ser só:

int        troca_palavra_na_frase(char* frase, char* palavra, char* palavra_nova)
{
    int t = strlen(palavra);
    if (t != strlen(palavra_nova)) return -2;
    if (strlen(frase) < strlen(palavra)) return -3;
    char* pos = strstr(frase, palavra);   // retorna 0 ou o endereco da palavra na frase
    if (pos == 0) return -1;              // nao tinha a palavra na frase
    for (int i = 0; i < t; i += 1) *(pos + i) = *(palavra_nova + i); // posicao da troca
    return (pos - frase);    // so isso
}    // end troca_palavra_na_frase()

Só 4 linhas se não considerar os 3 testes óbvios...

 

Usando a linha de comando:

Abaixo está um programa desses, troca, que pode ser mais útil pra testar isso. Se chama assim, direto na linha de comando

       troca Frase Palavra Palavra_Nova

e o programa faz a troca usando as duas rotinas, a que troca a primeira ocorrência e devolve a posição e a que troca todas as ocorrências e devolve o total de substituições. Se algum dos argumentos tem espaços então se usam aspas

 

Exemplo da execução

troca Banananana na n4

    troca()

    frase ..........[Banananana]
    palavra ........[na]
    palavra nova ...[n4]

    retornou 2

    frase no final..[Ban4nanana]

testando trocar todas as ocorrencias da palavra na frase    retornou 4

    frase no final..[Ban4n4n4n4]

Exemplo da execução quando tem espaços nos argumentos

troca "frase abcd frasefraseXYZT" " abcd " "_ABCD_"

    troca()

    frase ..........[frase abcd frasefraseXYZT]
    palavra ........[ abcd ]
    palavra nova ...[_ABCD_]

    retornou 5

    frase no final..[frase_ABCD_frasefraseXYZT]

testando trocar todas as ocorrencias da palavra na frase    retornou 1

    frase no final..[frase_ABCD_frasefraseXYZT]

De todo modo, este programa abaixo implementa as DUAS rotinas

#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "string.h"

int        troca_palavra_na_frase(char*, char*, char*);
int        troca_toda_palavra_na_frase(char*, char*, char*);

int main(int argc, char** argv)
{
    if (argc < 4)
    {
        printf("\nARFNeto\n\n\tUse: troca Frase Palavra Palavra_Nova\n\n");
        return 0;
    }    // end if
    printf("\
    \n    troca()\n\n\
    frase ..........[%s]\n\
    palavra ........[%s]\n\
    palavra nova ...[%s]\n\n",
        argv[1], argv[2], argv[3]
    );
    int    n = troca_palavra_na_frase(argv[1], argv[2], argv[3]);
    printf("    retornou %d\n\n", n);
    printf("    frase no final..[%s]\n\n", argv[1]);

    printf("testando: trocar TODAS as ocorrencias da palavra na frase");
    n = troca_toda_palavra_na_frase(argv[1], argv[2], argv[3]);
    printf("    retornou %d\n\n", n);
    printf("    frase no final..[%s]\n\n", argv[1]);
    return 0;
}


int        troca_palavra_na_frase(char* frase, char* palavra, char* palavra_nova)
{
    int t = strlen(palavra);
    if (t != strlen(palavra_nova)) return -2;
    if (strlen(frase) < strlen(palavra)) return -3;
    char* pos = strstr(frase, palavra);            // retorna 0 ou o endereco da palavra na frase
    if (pos == 0) return -1;                    // nao tinha a palavra na frase
    for (int i = 0; i < t; i += 1) *(pos + i) = *(palavra_nova + i); // retorna a posicao da troca
    return (pos - frase);    // so isso
}    // end troca_palavra_na_frase()


int        troca_toda_palavra_na_frase(char* frase, char* palavra, char* palavra_nova)
{
    int n, quantos = 0;
    char* indice = frase;
    do
    {
        n = troca_palavra_na_frase(indice, palavra, palavra_nova);
        quantos += 1;
        if (n < 1) return quantos;        // acabaram as palavras na frase
        indice += n;        // adianta os indicadores
    } while (1>0);
}    // end troca_palavra_na_frase()

Nenhuma das funções tem mais que uns poucos comandos então nem vou postar o programa de teste no site onde tem os programas que eu posto às vezes aqui.. Um arquivo de saída com vários testes está anexado, bem como um arquivo com as linhas de execução do teste

saida-bat.txt teste.bat.txt

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites
1 hora atrás, arfneto disse:

Não. O enunciado NÃO diz para substituir todas as ocorrências, então basta a primeira. E tem uma pegadinha nesse caso que eu acho que seria maldade passar para os alunos

Mais também não sei onde posso entender que não, isso fica vago pra mim e por essa razão perguntei ao autor; grande parte dos problemas são só de interpretação mesmo.

 

Ps.: Desculpa não ler sua postagem completa porque são grandes e não gosto disso prefiro quando vão direto ao ponto.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@MB_

Em 07/10/2019 às 15:54, MB_ disse:

Mais também não sei onde posso entender que não, isso fica vago pra mim e por essa razão perguntei ao autor; grande parte dos problemas são só de interpretação mesmo

É como o princípio jurídico da presunção de inocência: você é inocente até que se prove o contrário. O enunciado é um contrato. Como um contrato de prestação de serviços ou a especificação de um projeto: você não pode fazer menos do que está claro lá. Mas não deve fazer mais. Em certos casos você pode mesmo ter dificuldades comerciais ou jurídicas se fizer mais. 
No enunciado não diz que você deve substituir todas as ocorrências. Está no tópico.

 

Em 07/10/2019 às 15:54, MB_ disse:

Ps.: Desculpa não ler sua postagem completa porque são grandes e não gosto disso prefiro quando vão direto ao ponto

Talvez esses longos posts não tenham te agradado --- ainda que não tenha lido --- porque não é sua a dúvida afinal. 


Vou resumir o que tem lá. Espero que o resumo não seja longo:

  • uma rotina troca_palavra_na_frase(), com menos de 10 linhas,  que é uma possível solução para o problema, trocando a primeira ocorrência da palavra na frase
  • uma rotina troca_toda_palavra_na_frase(), também com menos de 10 linhas, que troca todas as ocorrências da palavra na frase
  • apresentação da rotina strstr() da bliblioteca padrão, que é praticamente a solução para o problema
  • uma discussão sobre a lógica desse problema e a aplicação da função strstr()
  • uma implementação de uma idêntica função strstr() para o caso provável de não se poder usar essa função na solução do enunciado
  • um programa de teste para as duas rotinas e que pega os 3 parâmetros da linha de comando, para não ter que ficar compilando o programa a cada teste
  • um script de teste que roda um conjunto razoável de testes
  • um arquivo de saída de uma execução desse script
  • um link para download desse material

Talvez --- e eu repito talvez --- se tiver você alguma dúvida sobre C ou C++ ou C# e postar algo aqui, aprecie o fato de alguém voluntariamente se dar ao trabalho de discutir desse modo "longo" a sua dúvida! 

 

Abraço a todos
 

  • Curtir 1
  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
14 horas atrás, arfneto disse:

É como o princípio jurídico da presunção de inocência: você é inocente até que se prove o contrário. O enunciado é um contrato. Como um contrato de prestação de serviços ou a especificação de um projeto: você não pode fazer menos do que está claro lá. Mas não deve fazer mais. Em certos casos você pode mesmo ter dificuldades comerciais ou jurídicas se fizer mais. 
No enunciado não diz que você deve substituir todas as ocorrências. Está no tópico.

Jurídico o quê? Kkkk prefiro deixar pra lá.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Obrigado a todos pelas respostas. Ainda me falta um domínio melhor da linguagem para conseguir assimilar todo o raciocínio do @arfneto, pois algumas passagens das suas linhas de código ainda me são estranhas, mas aos poucos vou chegando lá kkkkkk.

 

Apenas para esclarecer o enunciado: ele pede que substitua todas as ocorrências da palavra pela palavra nova na frase, exceto aquelas que não constituem uma palavra em si, mas apenas sílabas (acho que eu não havia deixado isso bem claro).

  • Obrigado 2

Compartilhar este post


Link para o post
Compartilhar em outros sites
27 minutos atrás, Claudir Junior disse:

pois algumas passagens das suas linhas de código ainda me são estranhas

 

:) Talvez devesse citar essas passagens estranhas e alguém poderia te ajudar. Talvez o próprio autor das estranhas passagens. Não acho que deva perder a oportunidade de perguntar qualquer coisa, afinal é um forum

 

29 minutos atrás, Claudir Junior disse:

exceto aquelas que não constituem uma palavra em si, mas apenas sílabas (acho que eu não havia deixado isso bem claro)

 

:D Sério? A noção de sílaba não ajuda em nada em C, C# ou C++. Imagine a frase 

"A casa de papel na verdade era de plastico", a palavra "de" e a palavra nova "quase de"

A frase deveria terminar "A casa quase de papel era na verdade quase de plastico" e você teria que cuidar de evitar um loop porque a palavra "de" retorna na palavra nova "quase de". Nesse caso não poderia tocar na palavra "verdade".

 

Nada especial, mas esse é um outro tema: é preciso definir uma palavra perfeitamente, estabelecer uma gramática, como 

- uma palavra é um sequência de caracteres delimitada por espaço ou TAB

- tratar os casos em que uma palavra começa já no início da frase, porque não teria delimitador

- tratar os casos em que a palavra ocorre no final da frase

 

Não existe noção de sílaba em programação. Deve estar definida perfeitamente no enunciado a noção de palavra. Esse é um tema comum no processamento de texto, como compiladores ou editores de texto.

 

Por acaso tem um tópico paralelo no forum sobre tratar palavras. Talvez ajude em algo. As rotinas e o método que expliquei aqui envolvem trocar uma ou todas ocorrências de uma string em outra maior ou igual à primeira. Talvez no outro tópico eu poste uma solução de como tratar palavras num sentido mais de gramática. Não é difícil incorporar aqui se entendeu as implementações oferecidas.

 

lá que ajude

talvez tenha algo 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
8 horas atrás, Claudir Junior disse:

Apenas para esclarecer o enunciado: ele pede que substitua todas as ocorrências da palavra pela palavra nova na frase, exceto aquelas que não constituem uma palavra em si, mas apenas sílabas (acho que eu não havia deixado isso bem claro).

Obrigado! Foi o que pensei. Sim, não ficou suficiente claro é verdade, porém notei um pouco dessa atitude em seu código. Por esse motivo minha equitação ...

 

 
Em 05/10/2019 às 16:33, MB_ disse:

@devair1010 se a última palavra na frase começa com as sílabas que tem a palavras A o algoritmo aplicará B. Pode visualizar isso também quando a frase é de uma só palavra.

 

Ex.: seja F: Banana, A: na, B: n4, a resposta é Ban4na.

 

 
Em 07/10/2019 às 15:54, MB_ disse:

Mais também não sei onde posso entender que não, isso fica vago pra mim e por essa razão perguntei ao autor; grande parte dos problemas são só de interpretação mesmo.

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro 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 publicações 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: minicurso “Como ganhar dinheiro montando computadores”

Gabriel TorresGabriel Torres, fundador e editor executivo do Clube do Hardware, acaba de lançar um minicurso totalmente gratuito: "Como ganhar dinheiro montando computadores".

Você aprenderá sobre o quanto pode ganhar, como cobrar, como lidar com a concorrência, como se tornar um profissional altamente qualificado e muito mais!

Inscreva-se agora!