INF1007 - Programação II

Lab 3 - Cadeias de caracteres (strings)



  1. Escreva uma função troca_letras que recebe como parâmetro o endereço de uma cadeia de caracteres e retorna um ponteiro para uma nova cadeia (alocada dinamicamente), onde todas as letras minúsculas da cadeia original foram trocadas por maiúsculas e vice-versa. Caracteres que não são letras (como dígitos, '.', espaço, etc.) não devem ser trocados. Sua função deve ter o seguinte protótipo:
    char *troca_letras(char *s);
    

    Na implementação de troca_letras você pode usar as seguintes funções da biblioteca padrão:

    • strlen (descrita em string.h), que recebe o endereço de uma cadeia (um char *) e retorna o número de caracteres nessa cadeia (sem contar o '\0').
    • isalpha, islower, isupper, toupper e tolower (descritas em ctype.h), que recebem como parâmetro um caractere.

      A função isalpha verifica se o caractere recebido é uma letra (retorna verdadeiro) ou não (retorna falso). A função islower verifica se o caractere recebido é uma letra minúscula (retorna verdadeiro) ou não (retorna falso); a função isupper faz o contrário (isto é, verifica se o caractere é uma letra maiúscula). A função toupper retorna um caractere que é a maiúscula da letra minúscula recebida; a função tolower faz o contrário.

    Caso não consiga alocar memória, sua função troca_letras deve retornar NULL.

    Teste troca_letras com alguns exemplos de cadeias, com letras minúsculas e maiúsculas e caracteres que não são letras. Você pode usar a função main dada abaixo. Note que o formato passado para scanf permite a leitura de cadeias contendo espaços e que o programa termina quando o usuário digita uma cadeia que começa com um '.'.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    char *troca_letras(char *s) {
    	... seu codigo aqui!
    }
    
    int main(void) {
      char string[81];
      char *ns;
      while (1) {
        printf("\nEntre uma cadeia: ");
        scanf(" %80[^\n]", string);
        if (*string == '.') break;
        ns = troca_letras(string);
        if (ns != NULL) {
          printf("Nova cadeia: %s\n", ns);
          free(ns);
        }
        else
          printf("Falha na troca!\n");
      }
      return 0;
    }
    




  2. Escreva uma função inverte que recebe como parâmetro uma cadeia de caracteres e retorna uma nova cadeia (alocada dinamicamente), que corresponde à cadeia original, lida de trás para frente. Por exemplo, recebendo como parâmetro a cadeia "Aluno", essa função retornaria a cadeia "onulA". Sua função deve ter o seguinte protótipo:
    char *inverte(char *s);
    

    Adapte a função main do exercício anterior para chamar a função inverte para cada cadeia entrada pelo usuário, exibindo depois a cadeia invertida.



  3. Um palíndromo é uma palavra que se pode ler tanto da esquerda para a direita como da direita para a esquerda. Alguns exemplos: arara, esse, ovo, rodador, sopapos.

    Escreva uma função palindromo que recebe como parâmetro uma cadeia e retorna 1 se a cadeia é um palíndromo e 0 caso contrário. Sua função deve ter o seguinte protótipo:

    int palindromo(char *s);
    

    Adapte agora a função main para chamar a função palindromo para cada cadeia entrada pelo usuário, exibindo depois um texto que informa se a cadeia é ou não um palíndromo.



  4. Escreva uma função ultimo_nome que recebe como parâmetro uma cadeia com o nome completo de uma pessoa e retorna um ponteiro (o endereço inicial) do último nome encontrado.

    Atenção: você não deve alocar uma nova cadeia para retornar o último nome!

    Sua função deve obedecer o protótipo:

    char *ultimo_nome(char *nome_completo);
    
    Veja alguns exemplos:
    • para a cadeia "Rafael de Moura Machado" a sua função deve retornar um ponteiro para "Machado"
    • para a cadeia "Jose Silva" a sua função deve retornar um ponteiro para "Silva"
    • para a cadeia "ZeNinguem" a sua função deve retornar um ponteiro para "ZeNinguem"

    Considere que há apenas um espaço entre os nomes e que após o último nome não há espaços.

    Adapte a função main do exercício anterior para testar ultimo_nome. Note que agora ela não deve liberar memória, pois ultimo_nome não aloca uma nova cadeia!

    Use pelo menos os exemplos acima para testar a sua função.



  5. Uma operação comum sobre cadeias de caracteres é a concatenação, isto é, a junção (cópia) dos caracteres de uma cadeia no final de uma outra cadeia. Por exemplo, se tivermos uma cadeia "Primeira" e concatenarmos a ela a cadeia "Segunda", obteremos como resultado a cadeia "PrimeiraSegunda".

    A biblioteca padrão de C oferece duas funções para a concatenação de cadeias (descritas em string.h):

      char *strcat(char *dest, char *src);
      char *strncat(char *dest, char *src, int n);
    

    A função strcat copia o conteúdo de src no final de dest, sobrescrevendo o '\0' no final de dest e acrescentando um '\0' para terminar a cadeia resultante. Note que a cadeia dest deve ter espaço suficiente para armazenar o resultado!

    A função strncat também concatena o conteúdo de src a dest, mas copia no máximo n caracteres. Neste caso, o espaço alocado para dest deve ser de pelo menos strlen(dest)+n+1.

    Crie um novo projeto no VStudio. Escreva uma função concatena que implemente a operação de concatenação oferecida por strncat, com o protótipo

    char *concatena(char *dest, char *src, int n);
    

    Escreva também uma função main para testar concatena. Chame concatena com alguns exemplos de pares de cadeias de destino e origem.

    Para simplificar, você pode inicializar as cadeias ao declará-las, por exemplo:

      char s1[50] = "primeira";
      char s2[] = " e segunda";
      char s3[] = " e terceira";
      
      printf("concatenadas = %s\n", concatena(s1, s2, strlen(s2)));
      printf("concatenadas com limite = %s\n", concatena(s1, s3, 5));
    



  6. Uma outra função da biblioteca padrão de C é strstr:
      char *strstr(char *src, char *sub);
    
    Essa função procura a primeira ocorrência do conteúdo de sub dentro da cadeia src e retorna um ponteiro (o endereço inicial) para essa ocorrência. Se sub não ocorre nenhuma vez em src, a função retorna NULL.

    Escreva uma função subcadeia que implemente a mesma funcionalidade de strstr (isto é, que faça exatamente o que strstr faz...). Ela deve ter um protótipo semelhante:

      char *subcadeia(char *src, char *sub);
    

    Teste sua função com alguns exemplos interessantes, como:

    • banana e ana: se você mandar imprimir a cadeia que corresponde ao endereço retornado por sua função, deverá ser exibida a cadeia anana
    • bananada e nada: se você mandar imprimir a cadeia que corresponde ao endereço retornado por sua função, deverá ser exibida a cadeia nada
    • bananada e ano: sua função deverá retornar NULL
    • aaabcd e aab: se você mandar imprimir a cadeia que corresponde ao endereço retornado por sua função, deverá ser exibida a cadeia aabcd