Ir ao conteúdo

Posts recomendados

Postado

EXEMPLO:

 

ENTRADA:     "A _linguagem_ C e muito poderosa! "

 

SAÍDA: " A <i>linguagem</i> C e muito poderosa! 

 

 

EXEMPLO 2:

 

ENTRADA:     "A linguagem *C* e mais rapida que *Python* "

 

SAÍDA: " A linguagem <b>C</b> e mais rapida que <b>Python</b>

 

 

 

N sei como substituir 1 carácter por uma palavra(string)...

Se alguém puder me ajudar tenho que substituir todos os * por <b> e pra fecha </b>

                                                                              todos os _ por <i> e pra fechar </1>

                               

 

 

                                

Obs: usar a função void replace(char * texto, int index, const char * tag);

                               /* substitui o caractere da posição index de texto pela tag */

  • Curtir 1
Postado

Veja se isso ajuda a resolver:

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

using namespace std;

int main()
{
    char text[60] = "A linguagem *C e mais rapida que Python";
    char saida[60];
    char id = '*';
    char id1[] = "<b>";
    char id2[] = "</b>";
    
    for (int i=0; i < strlen(text); i++)
        if (text[i] == id) //procura o '*'
        {
            strncpy(saida, text, i);//copia "A linguagem " para saida
            strcat(saida, id1);//acrescenta <b> - "A linguagem <b>"
            strcat(saida, text+i+1);//acrescenta o resto do texto (pula o *) A linguagem <b> e mais rapida que Python"
        }
    printf ("%s", saida);

    return 0;
}

O código acima substitui o * por <b>. Não funciona como você quer, mas é um começo. Veja se consegue fazer o resto.

  • Curtir 1
Postado
8 horas atrás, Gabriel Tellaroli Ramos disse:

EXEMPLO:

 

ENTRADA:     "A _linguagem_ C e muito poderosa! "

 

SAÍDA: " A <i>linguagem</i> C e muito poderosa! 

 

 

EXEMPLO 2:

 

ENTRADA:     "A linguagem *C* e mais rapida que *Python* "

 

SAÍDA: " A linguagem <b>C</b> e mais rapida que <b>Python</b>

 

 

 

N sei como substituir 1 carácter por uma palavra(string)...

Se alguém puder me ajudar tenho que substituir todos os * por <b> e pra fecha </b>

                                                                              todos os _ por <i> e pra fechar </1>

                               

 

 

                                

Obs: usar a função void replace(char * texto, int index, const char * tag);

                               /* substitui o caractere da posição index de texto pela tag */

Olá Gabriel!

 

Esse nome e essa declaração não foram provavelmente boa escolha. Mas pelo exemplo você quer envolver um único caracter por tags de abertura e fechamento como em linguagens de marcação, tipo XML ou HTML. Como por exemplo é comum usar <b></b> para negrito e <i></i> para itálico. Essas " tags" envolvem o argumento. 

 

O normal seria usar outra string como parâmetro mesmo, para trocar por exemplo rápida por <b>rápida</b>  e devolver o endereço da string nova também, porque assim você poderia usar em expressões.

Muitas das rotinas da biblioteca de manipulação de strings do C fazem isso, por uma boa razão. Algo assim:

char* insere_tags( char* texto, const char* palavra, const char* tag);

seria bem mais útil.

 

E aqui entre nós uma rotina replace() que não troca de fato nada é algo estranho :D 

 

De volta ao problema:

 

Dentro da rotina replace()

 

- você já sabe onde está a letra porque é o parâmetro indice

então

    - cria uma string nova pra montar a saída

    - copia a string original pra a string nova até a posição imediatamente anterior

    - copia  a tag de abertura para a nova string

    - copia a letra de volta para a nova string

    - e copia o resto da string de entrada

    -retorna

 

Dentro de main()

 

seja

    ts    o tamanho de texto, e

    tt     o tamanho da tag

 

então sua string em replace() vai crescer e ficar com (tt+ts) caracteres porque afinal você vai chamar replace() mas ela não vai de fato fazer um replace e sim inserir a tag.

porque estou dizendo isso? porque você vai precisar saber o novo indice para o caracter depois de ter inserido a tag de abertura.

 

Exemplo:

char* texto       = "A linguagem C e mais";
char* tag_abre    = "<b>";
char* tag_fecha   = "</b>";
int   indice      = 12; // posicao do C
int   tt          = strlen(texto);
int   ts          = strlen(tag_abre);

Você vai chamar replace()

replace(texto, indice, tag_abre);

o texto aumentou em ts caracteres, que agora vem antes da letra que estava em indice, e a letra continua lá.

 

Então você chama replace() de novo

replace(texto, indice+ts, tag_fecha);

E pode imprimir o texto com aletra circundada pelas tags corretas

 

Só isso

 

 

 

 

  • Curtir 1
Postado

@arfneto @arfnetoVocê está ajudando a desenvolver um sistema de gerenciamento de weblog. Embora o weblog coloque todo o conteúdo direto no website em HTML, nem todos autores apreciam usar tags HTML em seus textos. Para tornar a vida deles mais fáceis, o weblog oferece uma sintaxe simples chamada atalhos para obter alguns efeitos textuais em HTML. Sua tarefa é, dado um documento escrito com atalhos, traduzi-lo para o HTML apropriado. Um atalho é usado para colocar texto em itálico. HTML faz isto com as tags e , mas no weblog um autor pode simplesmente colocar um pedaço de texto entre dois caracteres de sublinhado, '_'. Portanto, onde um autor escreve: A _linguagem_ C e muito poderosa! O weblog vai publicar o seguinte: A linguagem C e muito poderosa! Outro atalho serve para colocar texto em negrito, o que, em HTML, é feito com as tags e . O weblog permite aos autores fazer o mesmo com pares do caractere asterisco, '*'. Quando um autor escreve o texto: A linguagem *C* e mais rapida que *Python* Ele vai sair no weblog assim: A linguagem C e mais rapida que Python Entrada A entrada contem vários casos de teste. Cada caso de teste é composto por uma linha que contem uma string texto, com zero ou mais usos dos atalhos itálico e negrito. Cada texto tem de 1 a 50 caracteres, inclusive. Os únicos caracteres permitidos no texto são os caracteres alfabéticos (de 'a' a 'z' e de 'A' a 'Z'), o sublinhado ('_'), o asterisco ('*'), o caractere de espaço e os símbolos de pontuação ',', ';', '.', '!', '?', '-', '(' e ')'. O caractere sublinhado '_' ocorre no texto um número par de vezes. O asterisco '*' também aparece um número par de vezes no texto. Nenhuma substring do texto entre um par de sublinhados ou entre um par de asteriscos pode conter outros sublinhados ou asteriscos, respectivamente. Saída Para cada linha de entrada seu programa deve gerar uma linha de saída com o texto traduzido para HTML como demonstrado nos exemplos abaixo. Para tornar itálico um pedaço de texto no HTML, você deve iniciar este pedaço com a tag e terminá-lo com a tag . Para texto em negrito, inicie com e termine com .

 

 

Para resolver este problema você deve obrigatoriamente implementar a seguinte função: /* substitui o caractere da posição index de texto pela tag */ void replace(char * texto, int index, const char * tag); 

 

O QUE EU TENHO QUE FAZER É ISSO usei um pouco da sua logica mas ainda n to conseguindo 

adicionado 41 minutos depois

@arfneto IC2-Trab1-2019.pdf

 

Cara n to conseguindo de jeito nenhum se tu conseguir pf me manda

adicionado 42 minutos depois

@vangodp IC2-Trab1-2019.pdf

 

 

Preciso fazer isso se puder me ajudar pf 

adicionado 42 minutos depois

@Flávio Pedroza IC2-Trab1-2019.pdf

O que eu preciso é isso ve se consegue , se puder me ajudar pf

 

Postado

@Gabriel Tellaroli Ramos O enunciado é bem ruim hein? Tem erros de concordância e escreve demais pra dizer pouco. E porque asterisco e sublinhado são atalhos e <b></b> e <i></i> são tags>? Quando tem uma letra é atalho? :D asterisco e sublinhado são tags...

E já que é um simples exemplo porque não usar sublinhado para texto sublinhado e usar a tag <u></u>? Folclórico.

 

Você escreveu a função replace() ao menos? Que fez até agora? Tem que entregar isso hoje, 14 mesmo? 

Postado

@arfneto Sim tenho que entregar hoje , o que eu tenho que fazer é substituir todos " _ " por  " <i> " só que vai aparecer um numero par de vezes então sempre vai ter que abrir com " <i> " e fechar com "</i>" e com o " * " a mesmo coisa só que substituir por "<b>" e "</b>"

adicionado 2 minutos depois

@arfneto

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


void replace(char * txt, int index, const char * tag);

int cont=1;

int main()
{

    int i;
    char txt[100];
    char* tag_abre[2] = {"<i>","<b>"};
    char* tag_fecha [2]  = {"</i>","</b>"};

    fgets(txt, 100, stdin);

    for(i=0; i<strlen(txt); i++)
    {
        if(txt=='_')
        {
            replace(txt,i,tag_abre[0]);
            cont++;
            i=i+3;
        }
    }
    puts(txt);

    return 0;
}


void replace(char * txt, int index, const char * tag)
{

    char txt2[200];

    if(cont==1)
    {
        strncpy(txt2, txt, index);
        strcat(txt2,tag);
        strcat(txt2,txt+index+1);
        strcpy(txt,txt2);
    }

    if(cont==2)
    {
        strncpy(txt2, txt, index);
        strcat(txt2,tag);
        strcat(txt2,txt+index+1);
        strcpy(txt,txt2);

        cont--;
    }


}

 

 

 

isso foi o que eu fiz ate agr mas n ta nem perto do certo porém n consigo sair disso to realmente desesperado

adicionado 30 minutos depois

@arfneto Minha logica é basicamente essa só preciso saber como substituir na função REPLACE()

 

 

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


void replace(char * txt, int index, const char * tag);

int main()
{

    char txt[51];
    char* tag_abre[2] = {"<i>","<b>"};
    char* tag_fecha [2] = {"</i>","</b>"};
    int i,conti=1,contb=1;

    fgets(txt, 50, stdin);

    for(i=0; i<strlen(txt); i++)
    {

        if( (txt=='_') && (conti%2 != 0))
        {

            replace(txt,i,tag_abre[0]);
            conti++;
        }
       
        if( (txt=='_') && (cont%2 = 0))
        {

            replace(txt,i,tag_fecha[0]);

        }
       
       
        if( (txt=='*') && (contb%2 != 0))
        {

            replace(txt,i,tag_abre[1]);
            contb++;

        }
        if( (txt=='*') && (contb%2 = 0))
        {

            replace(txt,i,tag_fecha[1]);

        }


    }
    return 0;
}

Postado

Leia minha assinatura para ver como postar código no fórum, sem que o fórum faça alterações que o façam parar de funcionar (observe todos os [ i ] sem espaços sumiram do seu código).

 

(cont%2 = 0) nos ifs estão errados, o operador de comparação de igualdade é == .

 

E a função replace é simples:

 

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

void replace(char * texto, int index, const char * tag);

int main()
{
    char texto[500] = "Hello_World";
    replace(texto, 5, "</i>");
    printf("%s", texto);

    return 0;
}

void replace(char *texto, int index, const char *tag){
    char cptexto[500];
    int lentag;
    
    lentag = strlen(tag);
    
    strcpy(cptexto, texto+index+1); //copia tudo que vem depois do caractere
    strcpy(texto+index, tag); //sobrescreve a tag no texto a partir da posição do caractere
    strcpy(texto+index+lentag, cptexto); //copia devolta para o texto depois da tag adicionada
}

 

  • Obrigado 1
Postado
26 minutos atrás, Gabriel Tellaroli Ramos disse:

@isrnick Nossa mano mt obrigado mesmo me ajudou mt cara n sei nem como agradecer :)

e obrigado n sabia como postar codigo aqui no forum...

 

Tenho dúvida de que possa simplesmente usar strcpy() para copiar as strings em replace(). Talvez perca pontos por isso. Afinal se pode usar strcpy() também pode usar strtok() e strstr() pra trocar as tags e não precisaria escrever replace(). Se puder usar, siga em frente, porque é sempre mais seguro :D E não fui eu que preparei o exercício afinal :) 


De todo modo veja esse programa que tem uma função que le o arquivo de entrada, uma implementação de replace() bem simples, que não usa strcpy() e mostra isso

[linha/tamanho] [linha]
[ 1,[ 1] []
[ 2,[32] [sem tags. linha em branco acima]
[ 3,[ 3] [__]
[ 4,[ 3] [**]
[ 5,[23] [__ tag subinhado vazia]
[ 6,[23] [** tag asterisco vazia]
[ 7,[28] [_a_ tag subinhado uma letra]
[ 8,[28] [*b* tag asterisco uma letra]
[ 9,[34] [A _linguagem_ C e muito poderosa!]
[10,[43] [A linguagem *C* e mais rapida que *Python*]
[11,[38] [_ _ __ _ yabba dabba _ * dooooo * ***]

Lidas 11 linhas
antes(....[teste]
depois:...[te<tag>te]
antes(....[teste]
depois:...[<tag>este]
antes(....[teste]
depois:...[test<tag>]

Eis o programa

#define _CRT_SECURE_NO_WARNINGS

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

// os testes
int fase1();
int fase2();

// a funcao
void        replace(char* texto, int index, const char* tag);

FILE* entrada;                    // o arquivo
int            total_linhas = 0;            // conta as linhas
int            maximo_linha = 50;            // max 50 letras
char        linha[51];                    // linhas aqui
int            tamanho_linha;                // tamanho da linha


int main(int argc, char** argv)
{
    fase1();    // so le o arquivo pra testar. E mostra as linhas
    fase2();    // testa replace
    return 0;
}    // end main()


//
// le o arquivo de entrada
// mostra as linhas
// mostra os tamanhos
//
int fase1()
{
    entrada = fopen("entrada.txt", "r");
    if (entrada == NULL)
    {
        perror("Deu esse erro");            // deu pau
        return 0;
    }    // end if

    printf("[linha/tamanho] [linha]\n");        // com legenda :)
    while (!feof(entrada))
    {
        total_linhas += 1;
        fgets(linha, 50, entrada);            // le a linha n
        tamanho_linha = strlen(linha);
        linha[tamanho_linha - 1] = 0;            // termina a string porque
                                            // e nao \0 e vamos mostrar na tela
        printf("[%2d,[%2d] [%s]\n", total_linhas, tamanho_linha, linha);    // mostra
    }
    printf("\nLidas %d linhas\n", total_linhas);
    fclose(entrada);
    return 0;
}    // end fase1()


int        fase2()
{
    char        linha[200];
    // testa a funcao replace
    // tenta trocar o s por <tag>
    // deve ficar te<tag>te
    char* teste = "teste";

    strcpy(linha, teste);
    replace(linha, 2, "<tag>");

    // testa no comeco
    strcpy(linha, teste);
    replace(linha, 0, "<tag>");

    // testa no fim
    strcpy(linha, teste);
    replace(linha, 4, "<tag>");
    return 0;
}    // end fase2()


/*
        replace() substitui o caracter da posicao index em texto pela tag

        texto tem no maximo 50
        tag tem 3 ou 4:    <b> </b> <i> </i>

 */
void        replace(char* texto, int index, const char* tag)
{
    int                i;
    int                tam_texto = strlen(texto);
    int                tam_tag =    strlen(tag);
    char            nova[128];                    // tag no exemplo tem 3 ou 4
    // copia texto para a nova, até a posicao index
    for (i = 0; i < index; i++)
    {
        nova[i] = texto[i];
    }
    // agora copia a tag. i_tag aponta dentro da tag
    for ( int i_tag = 0; i_tag < tam_tag; i_tag++)
    {
        nova[i] = tag[i_tag];
        i += 1;
    }
    // agora copia o resto de texto depois da tag
    // em texto[index] estava o caracter que vamos
    // trocar pela tag, entao copia de texto[index+1] ate o fim
    for (int j = index+1; j < tam_texto; j++)
    {
        nova[i] = texto[j];                // copia o resto
        i += 1;                            // avanca o ponteira em nova[]
    }
    nova[i] = 0;                        // termina com um zero a string nova
    //
    printf("antes(....[%s]\n", texto);
    printf("depois:...[%s]\n", nova);
    // agora copia de volta de nova[] para texto[]
    tam_texto = strlen(nova);            // tamanho atualizado
    for (i = 0; i < tam_texto; i += 1)
    {
        texto[i] = nova[i];
    }
    // um zero no final pra terminar o texto[]
    texto[tam_texto] = 0;
    // so isso
    return;
}

E tem um arquivo de entrada anexo, que você pode usar para testar com as condições mais comuns e as do enunciado, claro...

 


 Pode ajudar. Tem muitos comentários. Atente para a provável vantagem de escrever e testar aos poucos. Veja lá as funções fase1(), fase2()...

 

entrada.txt

  • Curtir 1
Postado

Se for fazer sem usar funções da biblioteca padrão dá pra fazer sem usar um vetor auxiliar para copiar o texto, faz as alterações diretamente dentro do vetor do texto original. Pra isso basta mover tudo que vem depois do index para a frente, abrindo espaço suficiente para escrever a tag na posição correta, para mover os caracteres para a frente deve copiar os caracteres no sentido do fim para o começo da string, começando a partir de uma posição strlen(tag)-1 além do fim da string.

Postado
2 horas atrás, isrnick disse:

Se for fazer sem usar funções da biblioteca padrão dá pra fazer sem usar um vetor auxiliar para copiar o texto

Claro, mas esse é um programa para iniciantes e o algoritmo é destrutivo. Então se você usar o vetor inicial diretamente só vai dificultar a sua vida porque vai ficar mais difícil de testar porque vai zoar o vetor de entrada...

 

Recomendo muito fazer o simples e usar outro vetor, e abusar de printf() para imprimir os resultados intermediários e tal. Depois que estiver funcionando você pode alterar seu programa, apagar ou coentar os printf() e usar um vetor só.

 

 @Gabriel Tellaroli Ramos Se não terminou ainda o trabalho, espero que ao menos tenha concluído a replace() 

e recomendo pensar numa função assim

int        insere_par_de_tags(
    char* texto,              // a cadeia
    const char atalho,        // o atalho, * ou _ no enunciado
    const char* tag_abre,     // a nova tag de abertura
    const char* tag_fecha     // e de fechamento
);

que faz o que parece considerando o nome, troca um atalho por um par de tags usando replace() e você usaria assim

        insere_par_de_tags(linha, '*', "<b>", "</b>");
        insere_par_de_tags(linha, '_', "<i>", "</i>");

É o caminho mais curto,  possivelmente

 

se já terminou por exemplo para os asteriscos, basta ir lá e trocar os valores pelos dos argumentos porque o resto vai continuar funcionando, certo? 

Veja um loop para uma rotina que funciona:

    entrada = fopen(arquivo, "r");
    if (entrada == NULL)
    {
        perror("Abrindo o arquivo deu esse erro");    // deu pau
        return 0;
    }    // end if

    printf("[linha/tamanho] [linha]\n");            // com legenda :)
    while (!feof(entrada))
    {
        total_linhas += 1;
        fgets(linha, 50, entrada);            // le a linha n
        tamanho_linha = strlen(linha);
        linha[tamanho_linha - 1] = 0;            // termina a string porque
                                            // e nao \0 e vamos mostrar na tela
        printf("Entrada:\n[%2d,[%2d] [%s]\n", total_linhas, tamanho_linha, linha);    // mostra
        insere_par_de_tags(linha, '*', "<b>", "</b>");
        insere_par_de_tags(linha, '_', "<i>", "</i>");
        printf("Saida:\n[%2d,[%2d] [%s]\n", total_linhas, tamanho_linha, linha);    // mostra
    }
    printf("\nLidas %d linhas\n", total_linhas);
    fclose(entrada);
    return 0;

E mostra isso

[29,[28] [_a_ tag subinhado uma letra]
Saida:
[29,[32] [<i>a</i> tag subinhado uma letra]
Entrada:
[30,[28] [*b* tag asterisco uma letra]
Saida:
[30,[32] [<b>b</b> tag asterisco uma letra]
Entrada:
[31,[34] [A _linguagem_ C e muito poderosa!]
Saida:
[31,[38] [A <i>linguagem</i> C e muito poderosa!]
Entrada:
[32,[43] [A linguagem *C* e mais rapida que *Python*]
Saida:
[32,[52] [A linguagem <b>C</b> e mais rapida que <b>Python</b>]
Entrada:
[33,[39] [_ _ __ _ yabba dabba _ * dooooo * ****]
Saida:
[33,[68] [<i> </i> <i></i> <i> yabba dabba </i> <b> dooooo </b> <b></b><b></b>]

 

adicionado 12 minutos depois

Se sua rotina replace() funciona, essa rotina

int insere_par_de_tags( char* texto, const char atalho, 
                        const char* tag_abre,  const char* tag_fecha);  

não precisa de mais que umas 20 linhas. E você chama duas vezes mudando os parâmetros como expliquei

        insere_par_de_tags(linha, '*', "<b>", "</b>");
        insere_par_de_tags(linha, '_', "<i>", "</i>");

Veja uma que funciona, com MUITOS comentários:
 

int        insere_par_de_tags(
    char* texto,            // a cadeia
    const char atalho,        // o atalho, * ou _ no enunciado
    const char* tag_abre,    // a nova tag de abertura
    const char* tag_fecha    // e de fechamento
)
{
    int                pos;
    int                tam_texto = strlen(texto);
    int                index = -1;
 
    do
    {
        // posiciona no primeiro asterisco do par. pode nao ter nenhum
        index = -1;        // indica que nao tem asteriscos
        for (pos = 0; pos < tam_texto; pos += 1)
        {
            if (texto[pos] != atalho) continue;
            index = pos;
            break;
        }
        if (index == -1) return 0;        // nao tinha mais asteriscos
        // entao o proximo asterisco esta em texto[index];
        // e o enunciado garante que estão em pares

        // troca o primeiro
        replace(texto, index, tag_abre);
        tam_texto = strlen(texto);
        for (pos = index + strlen(tag_abre); pos < tam_texto; pos += 1)
        {
            if (texto[pos] != atalho) continue;
            index = pos;Se
            break;
        }
        if (index == -1) return -1;        // nao podia acontecer entao retorna -1

        // troca o segundo
        replace(texto, index, tag_fecha);
        tam_texto = strlen(texto);
        // trocou um par. volta pro inicio a ver se tem outro
    } while (index > 0);
    return 0;                        // retorna ok
}    // end insere_par_de_tags()

 

Postado

@arfneto Sim, usar um vetor auxiliar facilita um pouco em programar uma solução, mas o problema do vetor auxiliar é que ele pode não ser grande o suficiente se o texto for muito longo, o que causaria sérios erros no resultado final, então para evitar erros ou seria necessário reservar uma quantidade exagerada de espaço para o vetor auxiliar, o que minimizaria a chance de erro mas não a eliminaria, ou precisaria usar alocação dinâmica (malloc) para reservar a quantidade exata conforme necessário dependendo do tamanho do texto, o que resolveria o problema ao custo de aumentar a complexidade da solução.

 

Mas eliminando a necessidade do vetor auxiliar não apenas resolve este problema, como também economiza memória.

 

Claro isso não é algo que um iniciante já tenha que considerar enquanto ainda está começando a aprender a programa, mas acho importante apontar onde os problemas podem ocorrer e onde o código pode ser melhorado, para aprender a pensar como um programador pois esse é o tipo de coisa que eventualmente vão ter que fazer.

 

A função sem usar vetor auxiliar poderia ficar assim:

void replace(char *texto, int index, const char *tag){
    int i;
    size_t lentexto, lentag;
    lentexto = strlen(texto);
    if (lentexto == 0 || lentexto <= index) {
        return;
    }
    lentag = strlen(tag);
    if(lentag != 0){
        //Move tudo depois do index lentag-1 casas para frente para abrir espaço:
        for(i = lentexto; i > index; i--){
            texto[i+lentag-1] = texto[i];
        }
        //Preenche o espaço com a tag:
        for(i = 0; i < lentag; i++){
            texto[index+i] = tag[i];
        }
    }
    else { //se a tag for uma string vazia
        //Move tudo depois do index uma casa para trás:
        for(i = index; i < lentexto; i++){
            texto[i] = texto[i+1];
        }
    }
}
Postado
27 minutos atrás, isrnick disse:

Sim, usar um vetor auxiliar facilita um pouco em programar uma solução, mas o problema do vetor auxiliar é que ele pode não ser grande o suficiente se o texto for muito longo, o que causaria sérios erros no resultado final

 

Talvez não tenha pensado nesse caso por completo :) não há qualquer garantia de que mesmo o vetor original tenha espaço alocado suficiente. Sequer se tem garantia de ser possível de aumentar porque a rotina pode ter sido chamada por engano com uma constante... 

Se você chamar replace() 

replace( "Qualquer coisa", 4, "azul" );

vai entender do que estou falando. A especificação é frágil. Só isso. Sem salvação.

32 minutos atrás, isrnick disse:

eliminando a necessidade do vetor auxiliar não apenas resolve este problema, como também economiza memória

 

Não, não resolve como te expliquei

32 minutos atrás, isrnick disse:

não é algo que um iniciante já tenha que considerar enquanto ainda está começando a aprender a programa, mas acho importante apontar onde os problemas podem ocorrer

 

Claro que aqui é um forum de discussão então é bom ver outro ponto de vista. Mas recomendo exatamente o contrário: justamente por ver onde os problemas podem ocorrer um iniciante --- ou mesmo um profissional que tente fazer isso na hora do almoço para ajudar alguém ;) --- não deve destruir o argumento de entrada antes de estar certo de que tudo está ok. Alguns mais precavidos até declarariam como  const o vetor inicial num primeiro momento e devolveriam o endereço novo na saída, que é o que a biblioteca padrão C faz em geral . Comentei isso numa mensagem anterior até.

37 minutos atrás, isrnick disse:

para aprender a pensar como um programador pois esse é o tipo de coisa que eventualmente vão ter que fazer.

Talvez a noção do que um programador irá fazer não esteja assim tão claramente estabelecida e te dei ao menos um argumento

 

O problema oferecido nem é assim muito bom, mas tem o mérito --- raro nesses programas para iniciantes --- de tentar mostrar ao aluno a vantagem possível de prosseguir a partir de elementos que ele criou, caso da rotina replace()

 

Um passo a mais seria o estudante pensar que todos os atalhos e tags tem processamento similar e que se poderia usar a partir de replace() algo como eu mostrei

        insere_par_de_tags(linha, '*', "<b>", "</b>");
        insere_par_de_tags(linha, '_', "<i>", "</i>");

E assim criar uma solução usando uma solução que usa uma solução, bem de acordo com o que um desenvolvedor precisa fazer

 

Abraço

Postado
15 horas atrás, arfneto disse:

Talvez não tenha pensado nesse caso por completo :) não há qualquer garantia de que mesmo o vetor original tenha espaço alocado suficiente. Sequer se tem garantia de ser possível de aumentar porque a rotina pode ter sido chamada por engano com uma constante... 

Se você chamar replace() 

replace( "Qualquer coisa", 4, "azul" );

vai entender do que estou falando. A especificação é frágil. Só isso. Sem salvação.

 

Pensei sim.

 

Você está apontando coisas que estão fora do escopo de controle da função replace() proposta para o exercício, do modo como ela foi proposta a função não tem como checar a validade dos parâmetros passados para a função, logo deve assumir que eles são adequados para que ela possa realizar seu trabalho. Várias funções da biblioteca padrão tem a mesma limitação, como scanf, strcat, sprintf, etc, e a responsabilidade fica a cargo do programador de garantir que os requisitos sejam atendidos ao chamar a função.

 

A proposta da biblioteca padrão para minimizar o problema foi criar funções "seguras" (com _s no final do nome) onde é adicionado um parâmetro a mais na função para indicar um limite máximo de caracteres, normalmente usado para indicar o tamanho do vetor de caracteres, para que este não seja excedido. Mas no caso aqui do tópico o enunciado do exercício especifica o protótipo da função replace(), e para fazer uma versão mais "segura" seria necessário modificá-lo.

 

Isto é um problema da linguagem C em geral, que é muito insegura, logo deve-se tomar cuidados especiais ao programar, mas nesse caso até poderia ativar warnings de compilação para quando usar um tipo incompatível ao chamar a função (como no caso de passar uma constante nesta função).

 

 

Entretanto o problema que apontei trata-se de outra coisa, é algo controlado pela própria função, e seria algo invisível para alguém que não programou a função (se ela fizesse parte de uma biblioteca por exemplo), e não saberia da limitação de tamanho do vetor auxiliar usado dentro da função, então a pessoa poderia passar todos os parâmetros adequadamente e mesmo assim a função produziria algo errado, e o programador ficaria sem entender por que...

 

 

17 horas atrás, arfneto disse:

Não, não resolve como te expliquei

 

Resolve o problema que apontei, você indicou outra coisa.

 

 

17 horas atrás, arfneto disse:

Claro que aqui é um forum de discussão então é bom ver outro ponto de vista. Mas recomendo exatamente o contrário: justamente por ver onde os problemas podem ocorrer um iniciante --- ou mesmo um profissional que tente fazer isso na hora do almoço para ajudar alguém ;) --- não deve destruir o argumento de entrada antes de estar certo de que tudo está ok. 

 

Qual seria a vantagem de preservar o texto no vetor original até formar o texto alterado no vetor auxiliar nesse caso?

 

A função replace() só tem a opção de não fazer nenhuma alteração (caso index seja inválido ou o texto seja uma string vazia logo não há nada para substituir), ou então deve alterar o texto original. Não há hipótese em que ele começa a fazer a alteração mas algo impede que finalize, e seja necessário cancelar a alteração, esta seria a situação onde seu argumento realmente seria um requisito para a função, mas não é o caso aqui.

 

Como falei até seria possível evitar erros usando alocação dinâmica de memória para criar o vetor auxiliar, mas não vejo nenhuma desvantagem de não usar um vetor auxiliar nesse caso, e até tem a vantagem de economizar memória.

 

 

17 horas atrás, arfneto disse:

Alguns mais precavidos até declarariam como  const o vetor inicial num primeiro momento e devolveriam o endereço novo na saída, que é o que a biblioteca padrão C faz em geral . Comentei isso numa mensagem anterior até.

 

Onde a biblioteca padrão do C faz isso?

 

Pelo contrário, em geral em funções destrutivas/construtivas ela retorna um endereço de memória que aponta para um vetor normal que foi passado como parâmetro de entrada da função (A função strtok() até retorna endereços apontando para várias posições diferentes do mesmo vetor de entrada cada vez que ela é chamada, e também altera o texto do vetor diretamente destruindo o texto original).

 

 

17 horas atrás, arfneto disse:

Talvez a noção do que um programador irá fazer não esteja assim tão claramente estabelecida e te dei ao menos um argumento

 

O conceito de aprender a pensar como programador que eu quis passar é o de programar código que sirva não apenas para atender o problema proposto, mas também sirva para outras situações que vão além das situações do problema proposto, podendo reutilizar o código para outras situações sem precisar fazer adaptações, e também de fazer o possível para eliminar ou minimizar ao máximo as possibilidades de erros que podem ocorrer ao executar o código em diferentes situações.

 

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

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!