AULA 11 - Programação 1 - Graduação

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

Objetivos

  • Vetores de char e Strings.
  • Processamento de Strings.

Tipo Char

Em aulas anteriores viu-se 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>
 
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");
}

Armazenamento de cadeias de caracteres em vetores


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 (0, não o caracter '0' que é o número 48 decimal em ASCII). Em inglês chama-se "string NULL terminated". Em algumas bibliografias e referências pode-se encontrar também: '\0'.

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

ExplicacaoString1.jpg

Assumi-se que cada caracter é armazenado em um byte. Uma string terminada em 0 facilita o seu processamento pois se pode facilmente detectar o seu final. Note no exemplo acima, que 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.

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.

FluxogramaContadorCaracteresCadeia.jpg

EXERCÍCIO 1: Colocar o procedimento acima na forma de um subprograma (função) que recebe como parâmetro o vetor e retorna um número inteiro correspondente ao tamanho da cadeia.

EXERCÍCIO 2: Elaborar um fluxograma para computador o número de ocorrências do caracter 'b' em uma string lida pelo teclado. Apresentá-lo na forma de um subprograma que retorna o número de ocorrências.

EXERCÍCIO 3: Estude a tabela ASCII e elabore um fluxograma para capitalizar todos os caracteres minusculos de uma string lida pelo teclado. Apresentá-lo como subprograma.

Função gets()


Esta função é utilizada em substituição ao scanf().

Forma geral:

char s[];
gets(s);

O usuário entra com uma string, que ser armazenada no vetor char s[]. A função gets() não é segura, por quê? Simplesmente porque com gets() pode ocorrer um estouro da quantidade de posições que foi especificada na string. Veja o exemplo abaixo:

#include <stdio.h>
void main()
{
    char buffer[10];
    printf("Entre com o seu nome: ");
    gets(buffer);
    printf("O nome é: %s\n", buffer);
}

Se o usuário digitar como entrada:

Douglas de Souza

Ou seja, digitar um total de 16 caracteres: 17 posições (incluindo o '\0' ) serão utilizadas para armazenar a string. Como a string buffer[10] só tem 10 caracteres, os 7 caracteres adicionais serão colocados na área de memória subsequente, escrevendo em uma região de memória que não está reservada para string. Este efeito é conhecido como "estouro de buffer" e pode causar problemas imprevisíveis. Uma forma de se evitar este problema é usar a função fgets().

Vetor de Char

É possível definir vetores do tipo char. Tais vetores permitem definir cadeias de caracteres. Para marcar um final de cadeia usa-se o número 0 (NULL),

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>
void main ()
{
   char alfa[50];

   int i=0;

   printf ("Entre com a cadeia: ");
   gets(alfa);
   while(alfa[i]!=0)
	i++;
   printf ("\nNumero de caracteres em %s = %d \n", alfa, i);
}
Exercícios
  1. Implementar um programa que computa o número de caracteres 'a' de uma string lida pelo teclado.
    #include <stdio.h>
    void main ()
    {
       char alfa[50];
       int cont;
       int i=0;
    
       printf ("Entre com a cadeia: ");
       gets(alfa);
    
       cont=0;
       while(alfa[i]!=0){
            if (alfa[i]=='a')
                cont++;
    	i++;
       }
       printf ("\nNumero de caracteres a em %s = %d \n", alfa, cont);
    }
    
  2. Implementar um programa que computa o número de ocorrências das subcadeias "ab" de uma string lida pelo teclado.
    #include <stdio.h>
    void main ()
    {
       char alfa[50];
       int cont;
       int i=0;
    
       printf ("Entre com a cadeia: ");
       gets(alfa);
    
       cont=0;
       while(alfa[i]!=0){
            if (alfa[i]=='a' && alfa[i+1]=='b') {
                cont++;
                i++; /* avançar uma posição */
            }
    	i++;
       }
       printf ("\nNumero de subcadeias ab em %s = %d \n", alfa, cont);
    }
    
  3. Implementar um programa que substitui todos os 'o' de uma cadeia por 'O.
    #include <stdio.h>
    void main ()
    {
       char alfa[50];
       int cont;
       int i=0;
    
       printf ("Entre com a cadeia: ");
       gets(alfa);
    
       cont=0;
       while(alfa[i]!=0){
            if (alfa[i]=='o')
                alfa[i]='O';
    	i++;
       }
       printf ("\nNova cadeia -> %s\n", alfa);
    }
    
  4. 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
#include <stdio.h>
void main ()
{
   char alfa[50], beta[50];
   int cont;
   int i=0;
 
   printf ("Entre com a cadeia:\n");
   gets(alfa);

   printf ("Entre com a cadeia:\n");
   gets(beta);
    
   cont=0;
   while(alfa[i]!=0 && beta[i]!=0){
        if (alfa[i]==beta[i])
            cont++;
	i++;
   }
   printf ("\nNumero de caracteres iguai em %s e %s na mesma posicao é %d \n", alfa, beta, cont);
}
|}
a) 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"
b) Implementar um programa que lê duas cadeias e imprime uma mensagem caso as cadeias seja iguais.



<< Aula 11 >>