AULA 10 - Programação 1 - Engenharia
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
- 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 - Implementar um programa que computa o número de caracteres 'a' de uma string lida pelo teclado.
Solução - Exercício 02 - 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; }
-
Implementar um programa que substitui todos os 'o' de uma cadeia por 'O.
Solução - Exercício 04 -
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; }
- 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"
- Implementar um programa que lê duas cadeias e imprime uma mensagem caso as cadeias seja iguais.
- 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 - 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.
- Fazer uma função que copia string mas que torna maiúsculo caracteres que estavam em minúsculo na string fonte.
- 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
-
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.
- 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; }
- 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.
- Implementar uma função que imprime uma string de forma invertida.
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);
}
|
Solução - Exercício 07 |
---|
Solução - Exercício 09 |
---|
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);
}
|
#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 |
---|