Título: Substituição de strings
Linguagem: C/C++
S.O.: DOS/Windows
Autor(es): Wenderson Teixeira


Substituição de strings

Replace.cpp

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <alloc.h>
#include <iostream.h>
#include <time.h>

/*--------------------------------------------------------------------
|   Substitue todas as ocorrencias de Str1 por Str2 em Src
|
|   Obs.:1) a string retornada por Replace nao e desalocada
|           automaticamente, e deve ser desalocada pelo
|           processo que o chamou
|        2) nao altera nenhum dos parametros de entrada
|        3) caso nao haja ocorrencias de Str1 em Src, sera retornada
|           uma copia de Src
|--------------------------------------------------------------------*/

char *Replace(const char *Src, const char *Str1, const char *Str2)
{
    // Cria uma copia de Src
    char *SrcCopy = strdup(Src);
    char *pTmp = SrcCopy;
    int sizeSrc = strlen(Src);
    int sizeStr1 = strlen(Str1);
    int sizeStr2 = strlen(Str2);
    do
    {
        // Acha o inicio de Str1 em Src
        pTmp = strstr(pTmp, Str1);
        if(pTmp)
        {
            int posStr1 = pTmp - SrcCopy;

            // Remove Str1 de Src
            int sizeRest = strlen(pTmp + sizeStr1);
            memmove(pTmp, pTmp + sizeStr1, sizeRest +
1);

            // Aloca a nova string com o novo tamanho
            sizeSrc = strlen(SrcCopy);
            SrcCopy = (
char *)realloc(SrcCopy, sizeof(char) * (sizeSrc + sizeStr2 + 1));

            // Insere Str2 em Src
            memmove(SrcCopy + posStr1 + sizeStr2, SrcCopy + posStr1, sizeRest +
1);
            memmove(SrcCopy + posStr1, Str2, sizeStr2);
            pTmp = SrcCopy + posStr1 + sizeStr2;
        }
    }
while(pTmp);

    return SrcCopy;
}


/*--------------------------------------------------------------------
|   Substitue todas as ocorrencias de Str1 por Str2 em Src
|
|   Obs.:1) a string retornada por OptimizedReplace nao e desalocada
|           automaticamente, e deve ser desalocada pelo
|           processo que o chamou
|        2) nao altera nenhum dos parametros de entrada
|        3) caso nao haja ocorrencias de Str1 em Src, sera retornada
|           uma copia de Src
|        4) Caso Str1 seja maior que Srt2, nao serao feitas alocacoes
|           ganhando-se em velocidade e menos fragmentacao de memoria
|--------------------------------------------------------------------*/

char *OptimizedReplace(char *Src, const char *Str1, const char *Str2)
{
    // Cria uma copia de Src
    char *SrcCopy = strdup(Src);
    char *pTmp = SrcCopy;
    int sizeStr1 = strlen(Str1);
    int sizeStr2 = strlen(Str2);
    int difSize = sizeStr2 - sizeStr1;  

    // Se Str2 for maior que Str1, execute o loop?
    if(difSize > 0)
    {
        do
        {
            // Acha o inicio de Str1 em Src
            pTmp = strstr(pTmp, Str1);
            if(pTmp)
            {
                int posStr1 = pTmp - SrcCopy;
                // Pega o tamanho de Src
                int sizeSrc = strlen(SrcCopy);
                // Pega o tamanho da string a partir do final de Str1 ate o final de Src
                int sizeRest = strlen(pTmp + sizeStr1);
                // Aloca memoria para comportar a nova string
                SrcCopy = (
char *)realloc(SrcCopy, sizeof(char *) * (sizeSrc + difSize + 1));
                // Insere Str2 no lugar de Str1 ja deslocando o fim de Src corretamente
                pTmp = SrcCopy + posStr1;
                memmove(pTmp + sizeStr2, pTmp + sizeStr1, sizeRest +
1);
                memmove(pTmp, Str2, sizeStr2);
                pTmp += sizeStr2;
            }
        }
while(pTmp);
    }
    // Otimizado para velocidade, sem executar nenhuma alocacao, ja que Str2 e menor que Str1
    else
    {
        do
        {
            // Acha o inicio de Str1 em Src
            pTmp = strstr(pTmp, Str1);
            if(pTmp)
            {
                // Pega o tamanho da string a partir do final de Str1 ate o final de Src
                int sizeRest = strlen(pTmp + sizeStr1);
                // Insere Str2 no lugar de Str1 ja deslocando o fim de Src corretamente
                memmove(pTmp + sizeStr2, pTmp + sizeStr1, sizeRest +
1);
                memmove(pTmp, Str2, sizeStr2);
            }
        }
while(pTmp);
    }

    return SrcCopy;
}

int main(int ArgC, char *ArgV[])
{
    cout <<
"Teste de Rotina para Substituicao de String" << endl;
    cout <<
"    By Wenderson Teixeira" << endl;
    cout <<
"       Coppyright VIC - 1998. Todos os Direitos Reservados." << endl << endl;

    if(ArgC < 3)
    {
        cout <<
"Uso : Replace Source Str1 Str2" << endl;
        cout <<
"   Onde:" << endl;
        cout <<
"       Source - string contendo as ocurrencias de Str1" << endl;
        cout <<
"       Str1   - string a ser substituida" << endl;
        cout <<
"       Str2   - nova string" << endl << endl;
        return 1;
    }

    cout <<
"String original: " << ArgV[1] << endl;
    cout <<
"Substituir: " << ArgV[2] << endl;
    cout <<
"Por       : " << ArgV[3] << endl << endl;
    
    char *Str;

    Str = Replace(ArgV[
1], ArgV[2], ArgV[3]);
    cout <<
"Utilizando Replace:" << endl;
    cout <<
"Nova String: " << Str << endl << endl;
    free(Str);

    Str = OptimizedReplace(ArgV[
1], ArgV[2], ArgV[3]);
    cout <<
"Utilizando OptimizedReplace:" << endl;
    cout <<
"Nova String: " << Str << endl << endl;
    free(Str);

    return 0;
}


1