AULA 10 - Programação 1 - Engenharia

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar

1 Objetivos

Após esta aula o aluno deverá ser capaz de:

  • Descrever como um caracter é representado no computador e como usar a tabela ASCII para verificar a representação de caracteres em binário, decimal;
  • Reconhecer a utilidade de caracteres especiais tais como o NUL e o NEWLINE;
  • Entender o que é uma string;
  • Construir definições/declarações de vetores de char no C e iniciar estes vetores com strings;
  • Construir código em C para processamento básico de strings armazenadas em vetores, usando indexação;
  • Construir funções que recebem como parâmetro vetores de char e utilizar o passagem por referência (endereço);

2 Revisando o Tipo Char

Em aulas anteriores vimos que um caracter pode ser representado por uma sequência de bits. Utilizando um código é possível definir o significado da sequência. Um código amplamente usado é o ASCII. Com 8 bits (7 no ASCII original) tem-se então a possibilidade de representar qualquer letra, número, ou símbolo (vírgula, ponto-e-vírgula etc). Note que um número representado em ASCII NÂO serve para realizar operações aritméticas. Trata-se de representação textual, por exemplo, um dígito de um número telefone.

Em síntese, uma variável do tipo caracter é tratada como um número inteiro e declarada com o tipo char, que na prática é um número inteiro de byte.

Exemplo

#include <stdio.h>
 
int main ()
{
  char x='A',y=65,w=0x41,z; /* três formas de representar a mesma coisa */
 
  scanf("%c",&z);
  printf("Caracter lido = %c\n",z);
  printf("Caracter lido = %d\n",z);
  printf("Caracter lido = %x\n",z);
  if (z==x)
      printf("Iguais 1\n");
  if (z==y)
      printf("Iguais 2\n");
  if (z==w)
      printf("Iguais 3\n");

  return 0;
}

3 Armazenamento de cadeias de caracteres em vetores

Nesta seção vamos discutir como armazenar caracteres em variáveis que apresentam-se como um vetor.

Uma cadeia de caracteres ou string nada mais é que uma sequência de caracteres ASCII. Para mantermos coerência com a linguagem C, vamos assumir que uma string bem comportada termina com um zero ou '\0' (note que não o caracter '0' que é o número 48 decimal em ASCII. Trata-se do inteiro 0 ou caracter NUL do ASCII que é representado como '\0'). Em inglês chama-se "string null terminated".

NOTA: O zero no final da string é uma forma de indicar que a mesma termina sem necessidade de armazenar o tamanho dela (algumas linguagens fazem isto).


Exemplo: A string "IFSC" armazenada em um vetor CADEIA, na memória de um computador, teria a seguinte implementação:

Estamos assumindo que cada caracter é armazenado em um byte. Uma string terminada em 0 facilita o seu processamento pois pode-se facilmente detectar o seu final. Note que no exemplo acima, a string está armazenada em um vetor CADEIA cujo tamanho excede ao da string. Os bytes que se seguem ao zero podem ser considerados lixo.

4 Processando cadeias de caracteres

Sabendo como uma string é armazenada na memória de um computador torna-se fácil processá-la. Por exemplo, vamos ver um algoritmo para contar o número de caracteres de uma string lida pelo teclado para dentro de um vetor CADEIA.

DADOS DE ENTRADA: cadeia de caracteres (string)

DADOS DE SAÍDA: tamanho da string


5 Vetor de char no C

É possível definir vetores do tipo char. Tais vetores permitem armazenar cadeias de caracteres. Para marcar um final de cadeia usa-se o número 0 (NULL). A função scanf pode ser usada para ler strings tal como indicado no exemplo abaixo:

Exemplo:

Fazer um programa para computar o número de caracteres de uma cadeia (string) lida pelo teclado.Use o comando while.

#include <stdio.h>
int main ()
{
   char alfa[50];

   int i=0;

   printf ("Entre com a cadeia: ");
   scanf("%s",alfa);
   while(alfa[i]!=0)
      i++;
   printf ("\nNumero de caracteres em %s = %d \n", alfa, i);
   return 0;
}
  • NOTA 1: O scanf NÃO testa se o buffer usado para leitura comporta a string. Isto pode ser uma fonte GRAVE de problemas.
  • NOTA 2: O scanf usa o espaço branco para separar strings na leitura. Para evitar isto pode-se usar scanf("%[^\n]s",alfa)
  • NOTA 3: A função gets pode também ser usada para leitura de strings mas a NOTA 1 se aplica também (ver discussão em

[1] e [2]). Observe que o uso de fgets é interessante para ter um controle de leitura.

5.1 Existe uma sequência de controle mais flexível que o %s: o %[].

Ver em [3]

Exemplo: Limitar o acesso a um buffer:

#include <stdio.h>

int main()
{
    char buffer[10];
    printf ("Entre com uma string\n");
    scanf ("%9[^\n]s", buffer);
    printf ("%s\n", buffer);
    return 0;
}


6 Vetor de Char Inicializado com String

Note que é possível criar um vetor já iniciado com uma string. Ver o exemplo abaixo:

#include <stdio.h>
int  main ()
{
   char alfa[50]="IFSC-SJ";

   int i=0;

   while(alfa[i]!=0)
	i++;
   printf ("\nNumero de caracteres em %s = %d \n", alfa, i);
   return 0;
}

7 Passando a string como parâmetro

A função abaixo permite computar o tamanho de uma string. Observe que tudo que foi comentado quanto a passagem de parâmetro continua valendo. O vetor teste é passado como "referência", ou seja, o vetor x, na chamada da função str_len() vai operar sobre o vetor teste. Para computar o tamanho da string, cada elemento do vetor será comparado com 0. Caso não seja, a variável i será incrementada.


#include <stdio.h>

int str_len(char x[])
{
  int i=0;
  while (x[i]!=0)
    i++;
  return i;
}
 
int main()
{
  char teste[]="IFSC-SJ";
  int tamanho;
 
  tamanho = str_len(teste);  
  printf("O tamanho da String %s eh: %d\n", teste, tamanho);
  return 0;
}

7.1 Exercícios

  1. Escreva um algoritmo para ler 5 caracteres do teclado, e depois mostre-os em ordem inversa à que foi digitada. OBS: Notar que a solução abaixo não se utilizada leitura de string mas sim leitura de caracter por caracter armazenado-os em sequÊncia sem o armazenamento do NUL ao final.
    Solução - Exercício 01
  2. Implementar um programa que computa o número de caracteres 'a' de uma string lida pelo teclado.
    Solução - Exercício 02
  3. Implementar um programa que computa o número de ocorrências das subcadeias "ab" de uma string lida pelo teclado.
    Solução - Exercício 03
    //Autor : Victor Cesconetto De Pieri
    #include <stdio.h>
    int main ()
    {
       char alfa[50];
       int cont;
       int i=0;
    
       printf ("Entre com a cadeia: ");
       scanf("%s",alfa);
    
       cont=0;
       while(alfa[i]!=0){
            if (alfa[i]=='a'&&alfa[i+1]=='b') {//verifica se o caracter na posicao "i" corresponde a 'a' e o proximo(i+1) corresponde a 'b'
                cont++;
                i++; //avançar uma posição
            }
    	i++;
       }
       printf ("\nNumero de subcadeias ab em %s = %d \n", alfa, cont);
       return 0;
    }
    
  4. Implementar um programa que substitui todos os 'o' de uma cadeia por 'O.
    Solução - Exercício 04
  5. Implementar um programa que lê duas cadeias e conta o número de caracteres iguais ocupando a mesma posição. Exemplo: suponha as cadeias "casa" e "amora". Não existem caracteres iguais na mesma posição. Já as cadeias "casa" e "cada" possuem três caracteres iguais na mesma posição
    Solução - Exercício 05
    //Autor : Victor Cesconetto De Pieri
    #include <stdio.h>
    int  main ()
    {
       char alfa[50], beta[50];
       int cont;
       int i=0;
     
       printf ("Entre com a cadeia:\n");
       scanf("%s",alfa);
    
       printf ("Entre com a cadeia:\n");
       scanf("%s",beta);
        
       cont=0;
       while(alfa[i]!=0 && beta[i]!=0){
            if (alfa[i]==beta[i])//verifica se sao iguais, se sim soma 1 ao contador.
                cont++;
    	i++;
       }
       printf ("Numero de caracteres iguai em %s e %s na mesma posicao é %d \n", alfa, beta, cont);
       return 0;
    }
    
  6. Modificar o exercício anterior para que os caracteres não iguais sejam intercambiados (mas continue respeitando os finais das cadeias). Exemplo: "casa" e "malagueta" deve resultar em "mala" e "casagueta"
  7. Solução - Exercício 06
    //Autor : Victor Cesconetto De Pieri
    
    #include <stdio.h>
    void main ()
    {
       char alfa[50], beta[50],aux,aux2;
       int cont;
       int i=0;
     
       printf ("Entre com a cadeia:\n");
       scanf("%s",alfa);
     
       printf ("Entre com a cadeia:\n");
       scanf("%s",beta);
     
       cont=0;
       while(alfa[i]!=0 && beta[i]!=0){
            if (alfa[i]==beta[i]){
                cont++;
    		}else{
    			aux = alfa[i];//conteudo da posição "i" de alfa para aux
    			aux2 = beta[i];//conteudo da posicao "i" de beta para aux2
    			beta[i] = aux;//aux que contem o conteudo de alfa sendo passado para beta na posicao "i"
    			alfa[i] = aux2;//aux2 que contem o conteudo de beta sendo passado para alfa na posicao "i"
    		}
    	i++;
       }
       printf ("\nalfa: %s beta: %s N de caracteres iguais: %d \n", alfa, beta, cont);
    }
    
  8. Implementar um programa que lê duas cadeias e imprime uma mensagem caso as cadeias seja iguais.
  9. Solução - Exercício 07
  10. Elaborar uma função para copiar uma string que está em um vetor de char para outro vetor. Fazer um exemplo de uso no main.
    #include <stdio.h>
    void str_cpy(char dest[],char fonte[])
    {
    }
    
    main()
    {
      char alfa[30],beta[30]="IFSC";
    
      str_cpy(alfa,beta);
      printf("%s\n", alfa);
    }
    
    Solução - Exercício 08
  11. Fazer uma variação do str_cpy que retorna um inteiro correspondente ao tamanho da string copiada. Mostrar o funcionamento da função no main.
  12. Solução - Exercício 09
  13. Fazer uma função que copia string mas que torna maiúsculo caracteres que estavam em minúsculo na string fonte.
  14. Solução - Exercício 10
    //Autor: Victor Cesconetto De Pieri
    
    #include <stdio.h>
    
    void str_caps(char dest[],char fonte[])
    {
    	int i=0;
    	do{
    		dest[i] = fonte[i]-32;//o caracter 'a' = 97 na tabela ascii e o 'A' = 65 na tabela ascii, apenas subtraindo o inteiro 32 conseguimos trocar a letra de minuscula para maiuscula.
    	}while(fonte[i++]!=0);	
    }
    
     
    main()
    {
      char alfa[30],beta[30]="aluno";
     
      str_caps(alfa,beta);
      printf("%s\n", alfa);
          
    }
    
  15. Fazer uma função que concatena duas strings colocando a segunda string no final da primeira. Mostrar o funcionamento da função no main. USAR como apoio as funções strlen e strcpy da biblioteca do C
  16. #include <stdio.h>
    
    void str_cat(char str1[], char str2[])
    {
    }
    main()
    {
     char alfa[30]="Alo", beta[20]=" mundo";
     
     str_cat(alfa,beta);
     printf("%s\n", alfa);
     str_cat(alfa," Terra");
    }
    
    Solução - Exercício 11
  17. Fazer uma função que recebe como parâmetro uma string. Esta função deve remover a primeira vogal presente nesta string (da esquerda para a direita). Esta função deve também retornar o número de caracteres da string sem a vogal. Apresente na função main() um exemplo de funcionamento da função, usando o seu primeiro nome. Siga o esqueleto mostrado abaixo:
    /* o vetor x contém a string a ser processada */ 
    int remove_caracter(char x[])
    {
    }
    
    int main()
    {
      /* fazer um exemplo aqui usando o seu primeiro nome como teste */
      return 0;
    }
    

    Exemplo de possível saída:

    • Foi passada a string "ifsc". Após a chamada da função, a string será "fsc". A função retorna 3.
    • Foi passada a string "delta". Após a chamada da função, a string será "dlta". A função retorna 4.
  18. Implementar uma função para remover os n primeiros caracteres de uma string. Se preferir use o esqueleto da função abaixo.
    #include <stdio.h>
    #include <string.h>
    
    int remove_n_char(char x[], int n)
    {
        int tam, i;
        /* remover os n primeiros caracteres da string armazenada em x[]
        */
    
        tam = str_len(x); /* implementada acima */
        if (n>=tam) { /* se n for maior ou igual ao tamanho da string então deixar string NULL e fazer tamanho zero */
             /* implementar */
        } else {
            tam = tam - n;  /* ajusta o tamanho da nova string, descontando os n caracteres */
            /* fazer um loop para deslocar tam caracteres a esquerda */
            /* ajustar o final da string */
        }
        return tam;
    }
    int main()
    {
        char nome[10]="IFSC-SJ";
        int tam;
    
        tam = remove_n_char(nome, 2);
        printf("%s - Tamanho %d\n", nome, tam); /* deve imprimir:  SC-SJ 5 */
    
        /* testar a função aqui usando o seu primeiro nome */
        return 0;
    }
    
  19. Implementar uma função que verifica se uma string é palíndromo. Ela deve retornar 0 se não for e 1 se for palíndromo. Não usar o conceito de ponteiro.
  20. Implementar uma função que imprime uma string de forma invertida.