Aula 13 - Cadeia de Caracteres PDF

Title Aula 13 - Cadeia de Caracteres
Course Algorítimos de Programação
Institution Universidade Federal de Mato Grosso do Sul
Pages 8
File Size 174.7 KB
File Type PDF
Total Downloads 96
Total Views 159

Summary

Aula 13 do curso de Algoritmos e Programação I...


Description

AULA

C ADEIAS DE

13

CARACTERES

Veremos nesta aula uma estrutura que possui tratamento especial na linguagem C: a cadeia de caracteres. Esta estrutura é similar a um vetor de caracteres, que vimos na aula 12, diferenciando-se apenas por conter um caractere especial no final, após o último caractere válido. Essa característica evita, em muitos casos, que tenhamos de manter uma variável que contenha o comprimento do vetor para saber o número de caracteres contidos nele. Outras características e diferenças importantes serão vistas nesta aula. Diversas funções que manipulam cadeias de caracteres estão disponíveis na biblioteca string da linguagem C. Mencionaremos algumas delas nesta aula e as restantes e os detalhes

serão vistos na aula 22. Esta aula é inspirada nas referências [6, 10].

13.1 Literais Vimos tomando contato com cadeias de caracteres desde quando escrevemos nosso primeiro programa na linguagem C. Por exemplo, na sentença abaixo:

printf("Programar é bacana!\n");

o único argumento passado para a função printf é a cadeia de caracteres (de formatação) "Programar é bacana!\n" . As aspas duplas são usadas para delimitar uma constante do tipo cadeia de caracteres, que pode conter qualquer combinação de letras, números ou caracteres especiais que não sejam as aspas duplas. Mesmo assim, é possível inserir as aspas duplas no interior de uma constante cadeia de caracteres, inserindo a sequência \" nessa cadeia. Na linguagem C, uma constante do tipo cadeia de caractere é chamada de literal . Quando estudamos o tipo de dados char , aprendemos que uma variável deste tipo pode conter apenas um único caractere. Para atribuir um caractere a uma variável, o caractere deve ser envolvido por aspas simples. Dessa forma, o trecho de código a seguir:

char sinal; sinal = ’+’;

138

13 C ADEIAS

139

DE CARACTERES

tem o efeito de atribuir o caractere cuja constante é ’+’ para a variável sinal , previamente declarada como um caractere com sinal. Além disso, aprendemos que existe uma distinção entre as aspas simples e as aspas duplas, sendo que no primeiro caso elas servem para definir constantes do tipo caractere e no segundo caso, para definir constantes do tipo cadeia de caracteres. Dessa forma, o seguinte trecho de código:

char sinal; sinal = "+";

não está correto, já que que a variável sinal foi declarada do tipo char , podendo conter um único caractere. Observe que a constante exige exatos dois compartimentos para armazenamento: o caractere cuja constante é ’+’ mais o caractere nulo cuja constante é ’\0’ . Dessa forma, é impossível armazenar esses dois caraceteres em um único compartimento de memória. Lembre-se finalmente que na linguagem C as aspas simples e as aspas duplas são usadas para definir dois tipos de constantes diferentes. Usamos literais especialmente quando chamamos as funções printf e scanf em um programa, ou seja, quando descrevemos cadeias de caracteres de formatação. Essencialmente, a linguagem C trata as literais como cadeias de caracteres. Quando o compilador da linguagem C encontra uma literal com n caracteres em um programa, ele reserva n + 1 compartimentos de memória para armazenar a cadeia de caracteres correspondente. Essa área na memória conterá os caracteres da cadeia mais um caractere extra – o caractere nulo – que registra o final da cadeia. O caractere nulo é um byte cujos bits são todos 0 (zeros) e é representado pela sequência ’\0’ . É importante destacar a diferença entre o caractere nulo e o caractere zero: o primeiro é um caractere não-imprimível, tem valor decimal 0 e constante ’\0’ ; o segundo é um caractere imprimível, tem valor 48, símbolo gráfico 0 e constante ’0’ . Ou seja, esses são caracteres muito diferentes. A literal "abc" pode ser armazenada como um vetor de quatro caracteres ou mais na memória, como mostra a figura 13.1. a

b

c

\0

Figura 13.1: Armazenamento de uma literal na memória. Por outro lado, uma literal também pode ser vazia. A literal "" é uma literal vazia, representada na memória como na figura 13.2. \0

Figura 13.2: Literal vazia na memória.

FACOM

UFMS

13 C ADEIAS

13.2

DE CARACTERES

140

Vetores de caracteres

Se queremos trabalhar com variáveis que podem armazenar mais que um único caractere, não nos sobram alternativas a não ser trabalhar com vetores de caracteres. Recorde que no exercício 13.6, devemos declarar dois vetores palavra e frase do tipo caractere e o fazemos da seguinte forma:

char palavra[MAX+1], frase[MAX+1];

Para solicitar que o usuário informe, por exemplo, o conteúdo da variável palavra , produzimos o seguinte trecho de programa:

printf("Informe a palavra: "); i = 0; do { scanf("%c", &palavra[i]); i++; } while (palavra[i-1] != ’\n’); m = i-1;

Para imprimir o conteúdo dessa mesma variável palavra , devemos escrever um trecho de programa da seguinte forma:

printf("Palavra: "); for (i = 0; i < m; i++) printf("%c", palavra[i]); printf("\n");

Note que sempre necessitamos de uma variável adicional para controlar o comprimento de um vetor de caracteres quando da sua leitura. A variável m faz esse papel no primeiro trecho de programa acima. Além disso, tanto para leitura como para escrita de um vetor de caracteres, precisamos de uma estrutura de repetição para processar os caracteres um a um. Com as cadeias de caracteres, evitamos esta sobrecarga de trabalho para o programador, como veremos daqui por diante.

13.3

Cadeias de caracteres

Algumas linguagens de programação de alto nível oferecem ao(à) programador(a) um tipo de dados especial para que variáveis do tipo cadeia de caracteres possam ser declaradas. Por outro lado, na linguagem C não há um tipo de dados como esse e, assim, qualquer vetor de FACOM

UFMS

13 C ADEIAS

DE CARACTERES

141

caracteres pode ser usado para armazenar uma cadeia de caracteres. A diferença, nesse caso, é que uma cadeia de caracteres é sempre terminada por um caractere nulo. Uma vantagem dessa estratégia é que não há necessidade de se manter o comprimento da cadeia de caracteres associado a ela. Por outro lado, esse mesmo comprimento, se necessário, só pode ser encontrado através de uma varredura no vetor. Suponha que necessitamos de uma variável capaz de armazenar uma cadeia de caracteres de até 50 caracteres. Como a cadeia de caracteres necessitará de um caractere nulo no final, então a cadeia de caracteres têm de ser declarada com 51 compartimentos para armazenar valores do tipo char , como mostrado a seguir:

#define MAX 50 . . . int main(void) { char cadeia[MAX + 1];

Na declaração de uma variável que pode armazenar uma cadeia de caracteres, sempre devemos reservar um compartimento a mais para que o caractere nulo possa ser armazenado. Como diversas funções da linguagem C supõem que as cadeias de caracteres são terminadas com o caractere nulo, se isso não ocorre em algum caso, o comportamento do programa passa a ser imprevisível. A declaração de um vetor de caracteres com dimensão MAX + 1 não quer dizer que o mesmo sempre conterá uma cadeia de caracteres com exatamente MAX caracteres. É importante destacar que o comprimento de uma cadeia de caracteres depende da posição do caractere nulo na cadeia, não do comprimento do vetor onde a cadeia está armazenada. Como em qualquer vetor, uma cadeia de caracteres também pode ser declarada e inicializada simultaneamente. Por exemplo,

char cidade[13] = "Campo Grande";

faz com que o compilador insira sequencialmente os caracteres da cadeia de caracteres "Campo Grande" no vetor cidade e então adicione o caractere nulo ao final da cadeia. Apesar de "Campo Grande" parecer uma literal, na realidade, a linguagem C a enxerga como uma abreviação para um inicializador de um vetor, que poderia ter sido escrito equivalentemente como abaixo: char cidade[13] = {’C’,’a’,’m’,’p’,’o’,’ ’,’G’,’r’,’a’,’n’,’d’,’e’,’\0’};

FACOM

UFMS

13 C ADEIAS

DE CARACTERES

142

Se um inicializador tem comprimento menor que o comprimento do vetor, o compilador preencherá os caracteres restantes do vetor com o caractere nulo. Se, por outro lado, o inicializador tem comprimento maior que a capacidade de armazenamento do vetor associado, os caracteres iniciais do inicializador serão armazenados no vetor, sem que o último deles seja o caractere nulo, impedindo assim que essa variável seja usada como uma legítima cadeia de caracteres. Veja o programa 13.1, que determina o comprimento de uma cadeia de caracteres. Programa 13.1: Determina o comprimento de uma cadeia de caracteres. #include int main(void) { char palavra[10] = "Ola!"; int n; n = 0; while (palavra[n] != ’\0’) n++; printf("O comprimento da palavra é %d\n", n); return 0; }

Há uma forma de ler e escrever cadeias de caracteres na linguagem C que facilita o trabalho de um(a) programador(a), evitando que sempre lance mão de uma estrutura de repetição para realizar uma dessas duas tarefas. O especificador de conversão %s no interior de uma cadeia de caracteres de formatação de entrada pode ser usado para mostrar um vetor de caracteres que é terminado por um caractere nulo, isto é, uma cadeia de caracteres. Assim se palavra é um vetor de caracteres terminado com o caractere nulo, a chamada da função abaixo:

printf("%s\n", palavra);

pode ser usada para mostrar o conteúdo completo da cadeia de caracteres palavra na saída padrão. Quando a função printf encontra o especificador de conversão %s , supõe que o argumento correspondente é uma cadeia de caracteres, isto é, um vetor de caracteres terminado por um caractere nulo. Podemos também usar a mesma cadeia de caracteres de formatação "%s" para leitura de uma cadeia de caracteres. A função scanf pode ser usada com o especificador de conversão %s para ler uma cadeia de caracteres até que a leitura de um branco seja realizada. Assim, a chamada da função scanf abaixo:

scanf("%s", palavra);

tem o efeito de ler uma cadeia de caracteres digitada pelo usuário e de armazená-la no vetor de caracteres palavra . FACOM

UFMS

13 C ADEIAS

143

DE CARACTERES

É muito importante ressaltar que, ao contrário das chamadas anteriores da função scanf quando trabalhamos com variáveis de tipos primitivos ou mesmo com compartimentos individuais de vetores, no caso de leitura de cadeias de caracteres o símbolo & não é adicionado como prefixo do identificador da variável. Veremos o porquê disto quando estudarmos apontadores. Se na execução da função scanf anterior alguém digita os caracteres abcdefg , a cadeia de caracteres "abcdefg" é armazenada no vetor palavra . Se, diferentemente, alguém digita os caracteres Campo Grande , então apenas a cadeia de caracteres "Campo" é armazenada no vetor palavra , devido ao branco ( ). Os caracteres restantes da cadeia digitada ficarão disponíveis no buffer de entrada até que uma próxima chamada à função scanf seja realizada. Para evitar brancos na leitura de uma cadeia de caracteres, usamos o especificador de conversão %[...] , que também é usado na leitura de cadeias de caracteres, delimitando, dentro dos colchetes, quais são os caracteres permitidos em uma leitura. Qualquer outro caractere diferente dos especificados dentro dos colchetes finalizam a leitura. Além disso, podemos inverter essas permissões, indicando o caractere ^ como o primeiro caractere dentro dos colchetes:

scanf("%[^\n]", palavra);

realiza a leitura de uma cadeia de caracteres, armazenando seu conteúdo no vetor de caracteres palavra . O caractere que finaliza a leitura é o \n . Qualquer outro caractere será lido e armazenado no vetor palavra . Também é muito importante destacar aqui que a função scanf termina automaticamente uma cadeia de caracteres que é lida com o especificador de conversão "%s" ou "%[...]" com um caractere nulo, fazendo assim que o vetor de caracteres associado se torne de fato uma cadeia de caracteres após sua leitura. Veja um exemplo simples sobre entrada e saída de cadeias de caracteres no programa 13.2. Programa 13.2: Entrada e saída de uma cadeia de caracteres. #include #define MAX 20 /* Recebe uma palavra com até MAX caracteres e imprime seu comprimento */ int main(void) { char palavra[MAX+1]; int n; printf("Informe uma palavra (com até %d caracteres): ", MAX); scanf("%s", palavra); n = 0; while (palavra[n] != ’\0’) n++; printf("A palavra [%s] tem %d caracteres\n", palavra, n); return 0; }

FACOM

UFMS

13 C ADEIAS

144

DE CARACTERES

Exercícios Para cada solução que construir para um exercício da lista abaixo, faça algumas simulações passo a passo da execução dessa solução, fornecendo entradas diferentes. 13.1 Dada uma frase com no máximo 100 caracteres, determinar quantos caracteres espaço a frase contém. Programa 13.3: Solução do exercício 13.1. #include #define MAX 100 /* Dada uma frase, determina quantos espaços ela possui */ int main(void) { char frase[MAX+1]; int esp, i; printf("Informe uma frase: "); scanf(" %[^\n]", frase); esp = 0; for (i = 0; frase[i] != ’\0’; i++) if (frase[i] == ’ ’) esp++; printf("Frase tem %d espaços\n", esp); return 0; }

13.2 Dada uma cadeia de caracteres com no máximo 100 caracteres, contar a quantidade de letras minúsculas, letras maiúsculas, dígitos, espaços e símbolos de pontuação que essa cadeia possui. 13.3 Dadas duas cadeias de caracteres cadeia1 e cadeia2 , concatenar cadeia2 no final de cadeia1 , colocando o caractere nulo no final da cadeia resultante. A cadeia resultante a ser mostrada deve estar armazenada em cadeia1 . Suponha que as cadeias sejam informadas com no máximo 100 caracteres. Exemplo: Se abcdef é armazenada na cadeia1 e ghijkl é armazenada na cadeia2 , então a cadeia abcdefghijkl deverá ser armazenada em cadeia1 e impressa na saída. 13.4 Dada uma cadeia de caractere cadeia com no máximo 100 caracteres e um caractere c , buscar a primeira ocorrência de c em cadeia . Se c ocorre em cadeia , mostrar a posição da primeira ocorrência; caso contrário, mostrar o valor -1 .

FACOM

UFMS

13 C ADEIAS

145

DE CARACTERES

Exemplo: Se o caractere forcido é a é a cadeia é zykgabcde, a saída deverá ser 4. 13.5 Dadas duas cadeias de caracteres cadeia1 e cadeia2 , cada uma com no máximo 100 caracteres, compará-las e devolver um valor menor que zero se cadeia1 é lexicograficamente menor que cadeia2 , o valor zero se cadeia1 é igual ou tem o mesmo conteúdo que cadeia2 , ou um valor maior que zero se cadeia1 é lexicograficamente maior que cadeia2 . Exemplo: Se abfgkl é armazenada na cadeia1 e abcdef é armazenada na cadeia2 , então a saída deverá ser 1. 13.6 Refaça o exercício 12.14, considerando agora que as sequências de caracteres fornecidas como entrada sejam cadeias de caracteres.

FACOM

UFMS...


Similar Free PDFs