Departamento de Ciência da Computação
IME/USP
MAC2166 Introdução a Computação
Strings e vetores de caracteres
1
Resumo:
O uso de strings facilita a manipulação de palavras e textos. Strings são basicamente vetores do tipo
char , porém diferentemente de simples vetores, strings são ”terminados”por um caractere ’\0’. Utilize
’%s’ para ler e imprimir strings nas funções scanf e printf . Você pode utilizar strings constantes
para carregar vetores de caracteres na sua declaração. Uma constante do tipo string é definida por uma
seqüência de caracteres entre aspas (lembre-se que uma constante do tipo char é um caractere entre apóstrofes).
2
Descrição:
Nessa lição vamos estudar como palavras (seqüências de caracteres) são tratadas no C.
Primeiro, vamos analisar um programa que carrega um vetor com n caracteres e os imprime logo em seguida:
#define MAX 100
#include <stdio.h>
#include <stdlib.h>
int main () {
int i;
char vet[MAX];
printf("Digite o tamanho do vetor: ");
scanf("%d", &n);
prinft("Digite a seqüência de caracteres: ");
for ( i=0 ; i<n ; i++ )
scanf("%c", &vet[i]);
prinft("A palavra que você digitou foi: ");
for ( i=0 ; i<n ; i++ )
printf("%c", vet[i]);
system("pause");
return 0;
}
Imagine um usuário precisando digitar seu nome para um formulário, e o computador pedindo para que ele,
primeiramante, digite o número de caracteres a serem lidos, como no exemplo acima. Isso complica muito uma
atividade que, a princı́pio, é bastante simples.
Uma forma de contornar esse problema seria utilizar um caractere especial como marcador, como por exemplo,
um ponto (’.’). Nesse caso, o computador poderia imprimir uma mensagem como: ”Digite seu nome terminado
por um ponto”. Obviamente, nenhuma pessoa poderia ter um ’.’ em seu nome, e essa solução provavelmente não
seria apropriada para entrar frases, ou textos com pontuação.
Strings são vetores de caracteres terminados por um caractere especial, o ’\0’ (barra zero). Esse caractere indica
o final da palavra ou texto e é normalmente tratado pelo próprio computador, facilitando assim a manipulação de
palavras.
3
Entrada e saı́da
Em C utiliza-se a seqüência ’%s’ para ler (usando scanf ) e imprimir (usando printf ) strings .
4
Exemplos
Na linguagem C, podemos inicializar strings colocando a seqüência de caracteres entre aspas, como mostra
o exemplo abaixo (tente descobrir a saı́da desse programa antes de continuar):
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
int main () {
/* Declarações */
int i;
char texto[MAX] = "apenas um exemplo.";
printf("%s\n", texto);
for (i=0; i<5; i++) texto[i] = ’i’ + i;
printf("%s\n", texto);
system ( "pause" );
return 0;
}
4.1
Descrição do programa
O vetor texto de caracteres, quando carregado, recebe automaticamente pelo compilador um caractere ’\0’,
como mostrado abaixo (as posições com ’?’ não foram inicializadas, ou seja, seu conteúdo é desconhecido):
texto:
a p e n a s
u m
e
x
e m p
l
o
. \0 ?
?
posição: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
O primeiro printf imprime o string ”apenas um exemplo.”, ou seja, percorre o vetor texto e imprime os
seus caracteres um a um, até encontrar um caractere ’\0’. Um trecho de código equivalente a printf("%s\n",
texto) seria:
i = 0;
while (texto[i] != ’\0’) {
printf("%c", texto[i]);
i++;
}
printf("\n");
ou ainda, usando um comando for :
2
for (i=0; texto[i] != ’\0’; i++)
printf("%c", texto[i]);
printf("\n");
Observe que, sem o uso de strings , precisamos conhecer o número de caracteres a serem impressos, e que o
uso de ”%s”simplifica bastante a impressão de strings .
Além do código de terminação (’\0’), não há diferença entre strings e vetores de caracteres, ou seja,
strings podem ser considerados vetores de caracteres terminados por um caractere ’\0’, como ilustrado pelo
primeiro for do programa, que coloca nas posições 0 a 4 do vetor texto os caracteres ’i’, ’j’, ’k’, ’l’, ’m’), ou
seja, o vetor texto ficaria assim:
texto:
i j k l m s
u m
e
x
e m p
l
o
. \0 ?
?
posição: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
e o string impresso pelo último printf seria ”ijklms um exemplo.”.
OBSERVAÇÃO: quando dizemos que o string é terminado por um ’\0’, significa que a parte válida dos
dados está antes desse caractere especial. As posições após o ’\0’, permanecem vazias, e podem ser utilizadas
quando o vetor é utilizado, por exemplo, para armazenar um outro string de maior comprimento.
4.2
Um outro exemplo
Vamos ver agora um programa que lê uma palavra e imprime os caracteres na ordem inversa a de leitura sem o
uso de strings , apenas para realçar a dificuldade de tratar palavras quando os caracteres são lidos um a um:
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
int main () {
/* Declarações */
int i,n;
char frase[MAX];
printf("Digite o numero de caracteres de seu texto: ");
scanf ("%d", &n);
printf("Digite o seu texto:\n");
for (i=0; i<n; i++)
scanf(" %c", &frase[i]); /* importante ter um espaco antes de %c */
printf("O seu texto na ordem inversa: \n");
for (i=n-1; i>=0; i--)
printf("%c", frase[i]);
printf("\n");
system ( "pause" );
return 0;
}
Observe que o programa precisa saber o número de caracteres a serem lidos, para carregar o vetor texto. Para
a palavra ”socorram-me”, que possui 11 caracteres, a saı́da seria ”em-marrocos”. Outra observação importante,
é que como o scanf lê TODOS os caracteres que vem do teclado (inclusive o enter), é necessário colocar um
espaço (branco) antes do %c do scanf , para que sejam eliminados os possı́veis separadores (branco, tabs,
3
enters, etc). Caso contrário, o enter dado após a leitura do tamanho da palavra se torna parte dos caracteres lidos,
e portanto faria parte da palavra (há muitos detalhes do C que precisam ser considerados quando se lê caracteres
um a um). Experimente rodar esse programa usando esse mesmo exemplo, mas sem o espaço antes do %c no
scanf .
4.3
Leitura de strings usando scanf
Em exemplos anteriores, os strings foram carregados como constantes, e o compilador sabe quando o
string começa e termina devido às aspas.
A leitura de strings usando scanf exige um pouco mais de cuidado, pois é necessário saber como o scanf
separa a entrada a partir do teclado em strings . Por convenção, os strings são delimitados por caracteres
separadores, como o branco, tabulação, enter, etc (mas não de pontuação, como vı́rgula, dois pontos, ou ponto
final). Por exemplo, no programa abaixo:
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
int main () {
int i,n;
char frase[MAX];
printf("Digite o numero de palavras: ");
scanf ("%d", &n);
printf("Digite todas as palavras e ao final tecle ENTER:\n");
for (i=0; i<n; i++) {
scanf("%s", frase);
printf(":%s:\n", frase);
}
system("pause");
return 0;
}
para a entrada 3 (como número de palavras) e as palavras ”um, dois, tres.”, imprimirá na saı́da o seguinte:
:um,:
:dois,:
:tres.:
Uma nova versão para o programa que lê uma palavra e a imprime em ordem inversa usando strings é dada
a seguir:
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
int main () {
int i,n;
char pal[MAX], inv[MAX];
printf("Digite sua palavra:\n");
scanf("%s", pal );
4
/* acha fim do string em pal */
for (n=0; pal[n] != ’\0’; n++);
/* monta um string inverso */
for (i=0; i<n; i++)
inv[i] = pal[n-1-i];
inv[n] = ’\0’; /* coloca o terminador no string inv */
/* imprime o string em na ordem inversa */
printf("O seu texto na ordem inversa: \n");
printf("%s\n", inv);
system ( "pause" );
return 0;
}
Vamos simular esse último programa com a frase ”socorram-me”. Após a declaração, os vetores pal e inv
possuem conteúdo incerto (ou seja, estão vazios), como mostra a figura abaixo:
pos:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
frase: ? ? ? ? ? ? ? ? ? ? ?
?
?
?
?
? ? ? ? ? ? ? ? ? ? ?
?
?
?
?
inv:
Após o scanf , o vetor pal é carregado com ”socorram-me”, e o string é automaticamente terminado por ’\0’,
como mostra a figura abaixo:
pos:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
frase: s o c o r r a m - m e \0 ?
?
?
inv:
? ? ? ? ? ? ? ? ? ?
?
?
?
?
?
O for após o scanf procura pela terminação do string , ou seja, procura pelo caractere ’\0’, e o encontra
na posição 11 do vetor, ou seja, n = 11, quando termina o for . A seguir, os caracteres de 10 a 0 são copiados
do vetor pal para as posições 0 a 10 do vetor inv (ou seja, quando i = 0 por exemplo, inv[0] recebe o
elemento n − 1 − i = 11 − 1 − 0 = 10 do vetor pal, ou inv[0] = frase[10]). Ao final do for , o
caractere ’\0’ é colocado ao final do string em inv para terminá-lo, de forma que terı́amos a seguinte situação:
pos:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
frase: s o c o r r a m - m e \0 ?
?
?
inv:
e m - m a r r o c o
s \0 ?
?
?
e o último printf apenas imprime o string em inv.
5
Exercı́cios recomendados
- Exercı́cio 6.6 do caderno: Dados dois strings (um contendo uma frase e outro contendo uma palavra), determine
o número de vezes que a palavra ocorre na frase.
Exemplo: Para a palavra ANA e a frase:
ANA E MARIANA GOSTAM DE BANANA
--------temos que a palavra ocorre 4 vezes na frase.
- Exercı́cio 8.17 (usa vetores de caracteres e não strings ).
5
Download

Strings - IME-USP