INF 1007 Programação II  
Aula 05 Cadeias de Caracteres  
Edirlei Soares de Lima  
<elima@inf.puc-rio.br>  
Caracteres  
Caracteres são representados através de códigos numéricos.  
Tabela de códigos:  
Define correspondência entre caracteres e códigos numéricos  
Exemplo: Tabela ASCII  
Alguns alfabetos precisam de maior representatividade  
alfabeto chinês tem mais de 256 caracteres  
no nosso caso, cada letra do alfabeto tem uma representação numérica  
diferente  
Códigos ASCII de Alguns Caracteres  
0
1
2
3
4
5
6
7
8
9
3
0
sp ! " # $ % & '  
4
0 ( ) * + , - . / 0 1  
5
0 2 3 4 5 6 7 8 9 : ;  
6
0 < = > ? @ A B C D E  
7
0 F G H I J K L M N O  
8
0 P Q R S T U V W X Y  
9
0 Z [ \ ] ^ _ ` a b c  
1
00 d e f g h i j k l m  
10 n o p q r S t u v w  
1
1
20 x y z { | } ~  
*
sp representa espaço  
82  
105 111  
32  
100 101  
32  
74  
97  
110 101 105 114 111  
Exemplo:  
R
i
o
d
e
J
a
n
e
i
r
o
Códigos ASCII de Caracteres de Controle  
0
7
8
9
nul null: nulo  
bel bell: campainha  
bs  
ht  
backspace: volta e apaga um caractere  
tab: tabulação horizontal  
1
1
0 nl  
3 cr  
newline ou line feed: muda de linha  
carriage return: volta ao início da linha  
1
27 del delete: apaga um caractere  
Caracteres  
Um caractere definido como uma constante é representado  
envolvido com aspas simples.  
Exemplo:  
char c = 'a';  
printf("%d %c\n", c, c);  
O printf imprime o conteúdo da variável usando dois formatos:  
com o formato para inteiro, %d, imprime 97  
com o formato de caractere, %c, imprime a (código 97 em ASCII)  
Caracteres  
Manipulando o código ASCII é possível criar uma função para  
converter minúsculas em maiúsculas:  
char maiuscula(char c)  
{
/* Verifica se é letra minúscula */  
if (c >= 'a' && c <= 'z')  
c = (c 'a') + 'A';  
return c;  
}
Essa função tira proveito da forma sequencial em que os  
caracteres são caracteres representados na tabela ASCII  
Cadeias de Caracteres  
Uma cadeia de caracteres, mais conhecida como string, é uma  
sequência de letras e símbolos.  
A linguagem C não possui um tipo de dado para armazenar  
strings, mas ela permite a criação de vetores de caracteres.  
Vetor do tipo char, terminado pelo caractere nulo ('\0')  
é necessário reservar uma posição adicional no vetor para o caractere de fim da  
cadeia  
As funções que manipulam cadeias de caracteres:  
recebem como parâmetro um vetor de char  
processam caractere por caractere até encontrar o caractere nulo, sinalizando o  
final da cadeia  
Cadeias de Caracteres  
A inicialização de uma cadeia de caracteres pode ser feita de  
forma semelhante a inicialização de um vetor (colocando cada  
caracteres entre aspas duplas)  
A linguagem C também fornece uma forma de inicialização  
mais simples utilizando aspas duplas (o caractere nulo é  
representado implicitamente)  
int main (void)  
int main (void)  
{
{
char cidade[] = "Rio";  
printf("%s \n", cidade);  
return 0;  
}
char cidade[]={'R', 'i', 'o', '\0'};  
printf("%s \n", cidade);  
return 0;  
}
Cadeias de Caracteres  
Exemplos:  
char S1[] = "";  
char S2[] = "Rio de Janeiro";  
char S3[81];  
char S4[81] = "Rio";  
S1 cadeia de caracteres vazia (armazena o caractere '\0')  
S2 armazena cadeia de 14 caracteres (em vetor com 15 elementos)  
S3 armazena cadeia com até 80 caracteres dimensionada com 81  
elementos, mas não inicializada  
S4 armazena cadeias com até 80 caracteres com os primeiros quatro  
elementos atribuídos na declaração {'R', 'i', 'o', '\0'};  
Leitura de Caracteres  
É possível utilizar o scanf para ler caracteres e cadeias de  
caracteres.  
O formato %c permite a leitura de um único caractere:  
char a;  
.
..  
scanf("%c", &a);  
..  
.
Leitura de Cadeias de Caracteres  
É possível utilizar o scanf para ler caracteres e cadeias de  
caracteres.  
O formato %s permite a leitura de uma cadeia de caracteres não  
brancos:  
char cidade[81];  
.
..  
scanf("%s", cidade);  
..  
.
Não é necessário usar &cidade pois cidade é um vetor (ponteiro)  
Somente lê palavras simples, se o usuário digitar “Rio de Janeiro”,  
somente “Rio” será capturado, pois %s somente uma sequência de  
caracteres não brancos.  
Leitura de Cadeias de Caracteres  
É possível utilizar o especificador de formato %[...] no scanf  
para definir os caracteres que podem e não podem ser lidos.  
%[…] os caracteres aceitos devem ser listados dentro dos colchetes.  
%[^…] os caracteres não aceitos devem ser listados dentro dos colchetes.  
Exemplos:  
%[aeiou]  
Lê sequências de vogais  
A leitura prossegue até encontrar um caractere que não seja uma vogal  
%[^aeiou]  
Lê sequências de caracteres que não são vogais  
A leitura prossegue até encontrar um caractere que seja uma vogal  
Leitura de Cadeias de Caracteres  
%[^\n]  
Lê uma sequência de caracteres até que seja encontrado o caractere de  
mudança de linha ('\n')  
A captura a cadeia de caracteres até que o usuário aperteEnter (nova linha)  
Permite ler cadeias de caracteres que com espaços em branco  
char cidade[81];  
.
..  
scanf(" %[^\n]", cidade);  
..  
.
pula eventuais caracteres brancos que precedam a cadeia de caracteres  
%80[^\n]  
Limita o tamanho máximo da cadeia de caracteres em 80  
char cidade[81];  
.
..  
scanf("%80[^\n]", cidade);  
..  
.
Manipulação de Cadeias de Caracteres  
Função “imprime”:  
Imprime na tela uma cadeia de caracteres, caractere por caractere,  
com uma quebra de linha no final:  
void imprime(char s[])  
{
int i;  
for (i=0; s[i] != '\0'; i++)  
printf("%c", s[i]);  
printf("\n");  
}
Ou usando o printf:  
void imprime(char s[])  
{
printf("%s\n", s);  
}
Manipulação de Cadeias de Caracteres  
Função “comprimento”:  
Retorna o comprimento de uma cadeia de caracteres  
Conta até encontrar o caractere nulo ('\0')  
O caractere nulo em si não é contado  
int comprimento(char s[])  
{
int i;  
int n = 0;  
for (i=0; s[i] != '\0'; i++)  
{
n++;  
}
return n;  
}
Manipulação de Cadeias de Caracteres  
Função “copia”:  
copia os caracteres de uma cadeia de origem (orig) para uma cadeia  
de destino (dest)  
A cadeia de destino deverá ter espaço suficiente  
void copia(char dest[], char orig[])  
{
int i;  
for (i=0; orig[i] != '\0'; i++)  
{
dest[i] = orig[i];  
}
dest[i] = '\0'; /* fecha a cadeia copiada */  
}
Manipulação de Cadeias de Caracteres  
Função “concatena”:  
copia os caracteres de uma cadeia de origem (orig) para o final de uma  
cadeia de destino (dest)  
void concatena(char dest[], char orig[])  
{
int i = 0; /* índice usado na cadeia destino */  
int j;  
/* índice usado na cadeia origem */  
while (dest[i] != '\0') /* acha o final da cadeia destino */  
{
i++;  
}
/* copia elementos da origem para o final do destino */  
for (j=0; orig[j] != '\0'; j++)  
{
dest[i] = orig[j];  
i++;  
}
dest[i] = '\0'; /* fecha cadeia destino */  
}
Manipulação de Cadeias de Caracteres  
Função “compara”:  
Compara, caractere por caractere, duas cadeias de  
caracteres  
usa os códigos numéricos associados aos caracteres para determinar a ordem  
relativa entre eles  
Valor de retorno da função:  
-1 se a primeira cadeia preceder a segunda  
1
0
se a segunda preceder a primeira  
se ambas as cadeias tiverem a mesma sequência de caracteres  
Manipulação de Cadeias de Caracteres  
int compara(char s1[], char s2[])  
{
int i;  
/* compara caractere por caractere */  
for (i=0; s1[i]!='\0' && s2[i]!='\0'; i++)  
{
if (s1[i] < s2[i])  
return -1;  
else if (s1[i] > s2[i])  
return 1;  
}
/* compara se cadeias têm o mesmo comprimento */  
if (s1[i]==s2[i])  
return 0;  
/* cadeias iguais */  
else if (s2[i]!= '\0')  
return -1;  
else  
/* s1 é menor, pois tem menos caracteres */  
/* s2 é menor, pois tem menos caracteres */  
return 1;  
}
Manipulação de Cadeias de Caracteres  
Biblioteca de cadeias de caracteres string.h:  
strlen: determina o comprimento de uma cadeia;  
strcpy: copia uma cadeia origem para outra destino;  
strcat: concatena duas cadeias;  
strcmp: compara duas cadeias;  
Funções da Biblioteca string.h  
A função strlen retorna o número de caracteres em  
uma cadeia de caracteres:  
O caractere nulo ('\0') não é contado  
int strlen(char str[])  
Exemplo:  
#
#
include <stdio.h>  
include <string.h>  
void main(void)  
{
char nome[] = "Curso de Programacao 1";  
printf("%s contem %d caracteres", nome, strlen(nome));  
}
Funções da Biblioteca string.h  
A função strcpy é usada para copiar o conteúdo de uma  
cadeia de caracteres (fonte), inclusive o caractere nulo, para  
outra cadeia (destino):  
char* strcpy(char destino[], char fonte[])  
Exemplo:  
#
#
include <stdio.h>  
include <string.h>  
void main(void)  
{
char nome[]="Joao da Silva";  
char aluno[50];  
strcpy(aluno, nome);  
printf("O nome do aluno eh %s”, aluno);  
}
Funções da Biblioteca string.h  
A função strcmp é usada para fazer a comparação lexicográfica  
de duas cadeias de caracteres:  
int strcmp(char str1[], char str2[])  
Se as cadeias são iguais, isto é, se str1 e str2 têm mesmo comprimento  
e caracteres iguais nos elementos de mesmo índice, a função retorna 0;  
Se str1 for lexicograficamente maior do que str2, a função retorna um  
valor positivo;  
Se str2 for lexicograficamente maior do que str1, a função retorna um  
valor negativo.  
Funções da Biblioteca string.h  
Exemplo de utilização da função strcmp:  
#
#
include <stdio.h>  
include <string.h>  
void main(void)  
{
char nome1[]="Joao da Silva";  
char nome2[]="Maria Fernanda";  
if(strcmp(nome1, nome2) == 0)  
printf("%s e igual a %s", nome1, nome2);  
else if(strcmp(nome1, nome2)>0)  
printf("%s vem depois de %s", nome1, nome2);  
else  
printf("%s vem depois de %s", nome2, nome1);  
}
Funções da Biblioteca string.h  
A função strcat é usada para concatenar o conteúdo de uma  
cadeia de caracteres (fonte) ao final de outra cadeia (destino):  
char* strcat(char destino[], char fonte[])  
Exemplo:  
#
#
include <stdio.h>  
include <string.h>  
void main(void)  
{
char nome[30]="Joao";  
char sobreNome[]=" da Silva";  
strcat(nome, sobreNome);  
printf("O nome do aluno eh %s", nome);  
}
Alocação Dinâmica de Cadeias de Caracteres  
Função “duplica”:  
copia os elementos de uma cadeia de origem (s) para uma cadeia de  
destino (d), alocada dinamicamente:  
#
#
include <stdlib.h>  
include <string.h>  
char* duplica(char* s)  
{
int n = strlen(s);  
char* d = (char*) malloc((n + 1) * sizeof(char));  
strcpy(d, s);  
return d;  
}
Alocação Dinâmica - Exemplo  
Encontrar o prefixo de n caracteres em uma cadeia de  
caracteres:  
Exemplo: “Programação II” -> “Prog” (prefixo de tamanho 4);  
#include <stdio.h>  
#include <stdlib.h>  
char *prefixo(char *str, int n)  
{
char *pre;  
int x;  
pre = (char*)malloc((n+1)*sizeof(char));  
for (x = 0; x < n; x++)  
pre[x] = str[x];  
pre[n] = '\0';  
return pre;  
}
Alocação Dinâmica - Exemplo  
[continuação…]  
int main (void)  
{
char nome[] = "PROGRAMACAO II";  
char *res = prefixo(nome, 4);  
printf("%s", res);  
return 0;  
}
Constante de Cadeia de Caracteres  
Representada por sequência de caracteres delimitada por aspas duplas;  
Comporta-se como uma expressão constante, cuja avaliação resulta no  
ponteiro para onde a cadeia de caracteres está armazenada;  
#include <string.h>  
#include <string.h>  
int main(void)  
int main (void)  
{
{
char cidade[4];  
strcpy(cidade, "Rio");  
printf("%s \n", cidade);  
return 0;  
char *cidade;  
cidade = "Rio";  
printf("%s \n", cidade);  
return 0;  
}
}
Constante de Cadeia de Caracteres  
Exemplos:  
char s1[] = "Rio de Janeiro";  
s1 é um vetor de char, inicializado com a cadeia Rio de Janeiro, seguida do  
caractere nulo;  
s1 ocupa 15 bytes de memória;  
é válido escrever s1[0]='X', alterando o conteúdo da cadeia para Xio de Janeiro,  
pois s1 é um vetor, permitindo alterar o valor de seus elementos;  
char* s2 = "Rio de Janeiro";  
s2 é um ponteiro para char, inicializado com o endereço da área de memória  
onde a constante Rio de Janeiro está armazenada;  
s2 ocupa 4 bytes (espaço de um ponteiro);  
não é válido escrever s2[0]='X', pois não é possível alterar um valor constante;  
Manipulação de Cadeias de Caracteres  
Implementação recursiva da função “imprime”:  
void imprime_rec(char* s)  
{
if (s[0] != '\0')  
{
printf("%c", s[0]);  
imprime_rec(&s[1]);  
}
}
int main (void)  
{
char cidade[] = "Rio de Janeiro";  
imprime_rec(&cidade[0]);  
return 0;  
}
Leitura Complementar  
Waldemar Celes, Renato Cerqueira, José Lucas  
Rangel, Introdução a Estruturas de Dados, Editora  
Campus (2004).  
Capítulo 6 Cadeia de caracteres  
Exercícios  
Lista de Exercícios 03 Strings e Recursão  
http://www.inf.puc-rio.br/~elima/prog2/