sexta-feira, 22 de dezembro de 2017

Problema de apagar, inverter e substituir palavras em um texto


Compartilhe!

O objetivo deste programa programa em C é realizar operações com palavras a fim de editar um texto (string ou array) a partir de comandos que podem ser: D - Apagar; I - Inverter (a ordem dos caracteres); R - Substituir; e Q - Sair do programa. Sendo, estas (D, I, R), operações com palavras. As palavras têm caracteres maiúsculos e minúsculos considerados iguais (ou seja, o programa é case insensitive).

A entrada consiste em um texto de até 1000 caracteres, e para cada operação o texto alterado deve ser exibido na tela como saída, e, antes de todas as outras saídas, também o texto original deve ser mostrado.

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

//Protótipos.
void excluaPalavra(char palavraMaiuscula[51], char textoMaiusculo[200][51], char texto2d[200][51], int nPalavras);
void substituaPalavra(char palavraAnteriorM[51], char entrada[51], char palavraMaiuscula[51], char textoMaiusculo[200][51], char texto2d[200][51], int nPalavras);
void invertaPalavra(char palavraMaiuscula[51], char textoMaiusculo[200][51], char texto2d[200][51], int nPalavras);
void guardaResultado(char texto2d[200][51], int nPalavras, char resultado[20001]);

int main(){

    char texto[1001],texto2d[200][51], entrada[51], textoMaiusculo[200][51], palavraMaiuscula[51], palavraAnteriorM[51], resultado[20001];
    int i, j=0, nPalavras=0, excluir=0, substituir=0, inverter=0;

    scanf("%[^\n]s",texto);//Ler o texto.

    //Converter a string em um array 2D  
    for (i = 0; texto[i]!= '\0'; i++){

        if (texto[i]==' '){

                texto2d[nPalavras][j] = '\0';//Quero criar dois arrays 2D: um só com palavras maiúsculas.
                textoMaiusculo[nPalavras][j] = '\0';
                nPalavras++;
                j = 0;

        }else{

            texto2d[nPalavras][j] = texto[i];
            if(texto[i] > 96 && texto[i] < 123)
                textoMaiusculo[nPalavras][j] = texto[i]-32;
            else textoMaiusculo[nPalavras][j] = texto[i];
            j++;

        }

    }
    texto2d[nPalavras][j] = '\0';//Define o fim do array.

    //Guarda o texto para exibir depois como saída.
    guardaResultado(texto2d, nPalavras, resultado);

    while(scanf("%s", entrada)!=EOF){//Ler entrada/ação. Enquanto não chegar ao final do arquivo:

     //Cria uma cópia da entrada só com caracteres maiúsculos.
     for(i = 0; entrada[i] != '\0'; i++){

  if(entrada[i] > 96 && entrada[i] < 123){ //Verifica se uma letra (char) é minúscula ou maiúscula segundo a tabela ASCII:

          palavraMaiuscula[i] = entrada[i]-32;//Transforma em uma letra maiúscula

  }else{
   palavraMaiuscula[i] = entrada[i];
      }
     }
     palavraMaiuscula[i]='\0';//Define o final da string.
        
     //Analisa ação anterior. As ações aqui são autoexplicativas.
     if(excluir){

  excluaPalavra(palavraMaiuscula, textoMaiusculo, texto2d, nPalavras), excluir=0;
  guardaResultado(texto2d, nPalavras, resultado);//Guarda resultado para exibir depois.
       
     }else if(substituir){

  if(palavraAnteriorM[0]!='\0'){
      substituaPalavra(palavraAnteriorM, entrada, palavraMaiuscula, textoMaiusculo, texto2d, nPalavras);
      substituir=0;
      palavraAnteriorM[0]='\0';//Zerar para uma próxima.
      guardaResultado(texto2d, nPalavras, resultado);
    
  }else{

      for(i=0;entrada[i]!='\0';i++)
          if(entrada[i] > 96 && entrada[i] < 123)
              palavraAnteriorM[i] = entrada[i]-32;//Guarda palavra na forma maiúscula.
      else palavraAnteriorM[i] = entrada[i];
      palavraAnteriorM[i]='\0';

  }
     }else if(inverter){
       
  invertaPalavra(palavraMaiuscula, textoMaiusculo, texto2d, nPalavras),inverter=0;
  guardaResultado(texto2d, nPalavras, resultado);
       
     }else //"Menu"
     if(strcmp(palavraMaiuscula,"D")==0){
  excluir=1;
     }else
     if(strcmp(palavraMaiuscula,"R")==0){
  substituir=1;
     }else
     if(strcmp(palavraMaiuscula,"I")==0){
  inverter=1;
     }else
     if(strcmp(palavraMaiuscula,"Q")==0){
  break;//Sai do While.
     }
    
     entrada[0]='\0';//Zerar a entrada para uma próxima.
   
    }
    printf("%s",resultado);//Imprimirá isto quando o usuário desejar sair do programa.
    return 0;

}

void guardaResultado(char texto2d[200][51], int nPalavras, char resultado[20001]){
    /*Para imprimir o texto resultante*/
        int i;
 for (i = 0;i < nPalavras + 1; i++){
         if(i) strcat(resultado, " ");//Coloca um espaço antes da palavra ser concatenada se ela não for a primeira.
  strcat(resultado,texto2d[i]);
        }
 
 //Remover os espaços que ficaram no final da string. A condição do for é "enquanto não for letra", a partir da tabela ASCII.
 for(i = strlen(resultado); !((resultado[i] > 96 && resultado[i] < 123)||(resultado[i] > 64 && resultado[i] < 91)); --i);
 resultado[i+1]='\n', resultado[i+2]='\0';//Colocar, nas posições seguintes à última letra, o \n e o \0 na string resultado.

}

void invertaPalavra(char palavraMaiuscula[51], char textoMaiusculo[200][51], char texto2d[200][51], int nPalavras){

    int k,l; char palavraASerInvertida[51];
/* Compara a palavraMaiuscula com as palavras do textoMaiusculo */  
    for (int i = 0;i < nPalavras+1; i++){
 
        if (strcmp(textoMaiusculo[i], palavraMaiuscula) == 0){
  k=0;
  //Após encontrar a palavra, define qual será invertida (pois existe a palavra toda maiúscula, a palavra que o usuário digitou para inverter e a palavra original do texto. Queremos inverter de acordo com a original do texto para manter o formato dos caracteres):
  for(l=0; l<strlen(palavraMaiuscula);l++)
   palavraASerInvertida[l]=texto2d[i][l];

  for(int j = (strlen(palavraMaiuscula)-1); j !=-1; j--) {//Inverte a palavra.
          texto2d[i][k] = palavraASerInvertida[j];
       textoMaiusculo[i][k]=palavraMaiuscula[j];
          k++;
  }

     }

    }

}

void substituaPalavra(char palavraAnteriorM[51], char entrada[51], char palavraMaiuscula[51], char textoMaiusculo[200][51], char texto2d[200][51], int nPalavras){

/* Compara a palavraMaiuscula com as palavras do textoMaiusculo */  
    for (int i = 0;i < nPalavras + 1; i++){

        if (strcmp(textoMaiusculo[i], palavraAnteriorM) == 0){

  strcpy(texto2d[i], entrada);//Função para copiar o conteúdo de uma string em outra.
  strcpy(textoMaiusculo[i], palavraMaiuscula);//Quero que nos dois arrays isso ocorra para que eu possa continuar o usando.
       
     }

    }

}


void excluaPalavra(char palavraMaiuscula[51], char textoMaiusculo[200][51], char texto2d[200][51], int nPalavras){

    int j=0;

/* Compara a palavraMaiuscula com as palavras do textoMaiusculo */  
    for (int i = 0;i < nPalavras+1; i++){


        if (strcmp(textoMaiusculo[i], palavraMaiuscula) == 0){

  for (j = i; j <= nPalavras; j++){
      //Reorganiza os arrays pegando a próxima palavra e colocando no lugar da anterior a partir da palavra a ser excluída.
      strcpy(texto2d[j], texto2d[j + 1]);
      strcpy(textoMaiusculo[j], textoMaiusculo[j + 1]);

  }

               nPalavras--;//Define que o número de palavras diminuiu.
        i--;
     }
    }

}