Caracteres e cadeia de caracteres IPC2 1999/2000 F. Nunes Ferreira Acetatos baseados no livro C: How to Program (second edition) H. M. Deitel P. J. Deitel Prentice Hall, 1994
Caracteres e cadeia de caracteres 2 Um caracter é um valor inteiro representado por esse caracter entre plicas 'z' representa o valor inteiro de z Em C, um caracter é um inteiro representado num byte Uma cadeia de caracteres é representada por uma série de caracteres entre aspas "Fernando Namora" Uma cadeia de caracteres é um array de caracteres indicando o caracter nulo ('\0'), o fim da cadeia...
3 Caracteres e cadeia de caracteres... Uma cadeia de caracteres é acedida através de um apontador para o primeiro caracter da cadeia char cor[] = "blue"; cria array cor com 5 elementos: 'b', 'l', 'u', 'e', '\0' char cor[] = {'b', 'l', 'u', 'e', '\0'}; equivalente ao anterior char *corptr = "blue"; cria o apontador corptr para o um array que contém "blue"
4 #include <stdio.h> main (void) { char cor[] = "blue", *corp; char *corptr = "red"; printf("*corptr = %c\n", *corptr); ++corptr; printf("*corptr = %c\n", *corptr); printf("*cor = %c\n", *cor); /* ++cor; */ seria ERRO!... corp = cor; printf("*corp = %c\n", *corp); ++corp; printf("*corp = %c\n", *corp);... *corptr = r *corptr = e *cor = b *corp = b *corp = l
5 Caracteres e cadeia de caracteres char outracor[10]; scanf("%s", outracor); outracor é nome de um array, não sendo necessário & Lê cadeia até encontrar espaço, nova-linha, EOF CTL - Z No final da cadeia acrescenta '\0'
6 Caracteres e cadeia de caracteres #include <ctype.h> manipulação de caracteres #include <stdlib.h> conversão de cadeia de caracteres #include <stdio.h> entrada/saída de caracteres e cadeias de caracteres #include <string.h> manipulação de cadeias de caracteres comparação de cadeias de caracteres pesquisa de cadeias de caracteres
7 Caracteres e cadeia de caracteres Funções de manipulação de caracteres #include <ctype.h> int isdigit(int c) devolve V(erdadeiro) se c é dígito decimal (0-9) int isalpha(int c) devolve V se c é letra (A-Z ou a-z) int isalnum(int c) devolve V se c é dígito ou letra (0-9, A-Z ou a-z) int isxdigit(int c) devolve V se c é dígito hexadecimal (A-F, a-f ou 0-9)
8 Caracteres e cadeia de caracteres Funções de manipulação de caracteres #include <ctype.h> (cont.) int islower(int c) devolve V se c é letra minúscula (a-z) int isupper(int c) devolve V se c é letra maiúscula (A-Z) int tolower(int c) converte c para minúscula, que é devolvida int toupper(int c) converte c para maiúscula, que é devolvida
9 Caracteres e cadeia de caracteres Funções de manipulação de caracteres #include <ctype.h> (cont.) int isspace(int c) devolve V se c é espaço(' '), form feed('\f'), nova linha ('\n'), return('\r'), tab('\t') e tab vertical('\v') int iscntrl(int c) devolve V se c é um caracter de controlo ('\t', '\v', '\f', '\a', '\b', '\r', ou '\n') int ispunct(int c) se c se pode imprimir, excepto espaço, letra ou dígito
10 Caracteres e cadeia de caracteres Funções de manipulação de caracteres #include <ctype.h> (cont.) int isprint(int c) se c se pode imprimir, incluindo espaço int isgraph(int c) se c se pode imprimir, não incluindo espaço
#include <stdio.h> /* string1.doc */ #include <ctype.h> main() { char charlido; printf("indicar caracter; EOF para terminar:"); while (EOF!= (charlido = getchar())){ getchar(); printf("isdigit(%c) = %d\n", charlido, isdigit(charlido)); printf("isalpha(%c) = %d\n", charlido, isalpha(charlido)); printf("isalnum(%c) = %d\n", charlido, isalnum(charlido)); printf("isxdigit(%c) = %d\n", charlido, isxdigit(charlido)); printf("islower(%c) = %d\n", charlido, islower(charlido)); printf("isupper(%c) = %d\n", charlido, isupper(charlido)); printf("tolower(%c) = %c\n", charlido, tolower(charlido)); printf("toupper(%c) = %c\n", charlido, toupper(charlido)); printf("isspace(%c) = %d\n", charlido, isspace(charlido)); printf("iscntrl(%c) = %d\n", charlido, iscntrl(charlido)); printf("ispunct(%c) = %d\n", charlido, ispunct(charlido)); printf("isprint(%c) = %d\n", charlido, isprint(charlido)); printf("isgraph(%c) = %d\n", charlido, isgraph(charlido)); } printf("indicar caracter; EOF para terminar:");...
Indicar caracter; EOF para terminar:a isdigit(a) = 0 isalpha(a) = 2 isalnum(a) = 2 isxdigit(a) = 128 islower(a) = 2 isupper(a) = 0 tolower(a) = a toupper(a) = A isspace(a) = 0 iscntrl(a) = 0 ispunct(a) = 0 isprint(a) = 2 isgraph(a) = 2 Indicar caracter; EOF para terminar:a isdigit(a) = 0 isalpha(a) = 1 isalnum(a) = 1 isxdigit(a) = 128 islower(a) = 0 isupper(a) = 1 tolower(a) = a toupper(a) = A isspace(a) = 0 iscntrl(a) = 0 ispunct(a) = 0 isprint(a) = 1 isgraph(a) = 1
Indicar caracter; EOF para terminar:* isdigit(*) = 0 isalpha(*) = 0 isalnum(*) = 0 isxdigit(*) = 0 islower(*) = 0 isupper(*) = 0 tolower(*) = * toupper(*) = * isspace(*) = 0 iscntrl(*) = 0 ispunct(*) = 16 isprint(*) = 16 isgraph(*) = 16 Indicar caracter; EOF para terminar: isdigit( ) = 0 isalpha( ) = 0 isalnum( ) = 0 isxdigit( ) = 0 islower( ) = 0 isupper( ) = 0 tolower( ) = toupper( ) = isspace( ) = 8 iscntrl( ) = 0 ispunct( ) = 0 isprint( ) = 64 isgraph( ) = 0
Indicar caracter; EOF para terminar: isdigit( ) = 0 isalpha( ) = 0 isalnum( ) = 0 isxdigit( ) = 0 islower( ) = 0 isupper( ) = 0 tolower( ) = toupper( ) = isspace( ) = 8 iscntrl( ) = 0 ispunct( ) = 0 isprint( ) = 64 isgraph( ) = 0 Indicar caracter; EOF para terminar: isdigit( ) = 0 isalpha( ) = 0 isalnum( ) = 0 isxdigit( ) = 0 islower( ) = 0 isupper( ) = 0 tolower( ) = toupper( ) = isspace( ) = 0 iscntrl( ) = 32 ispunct( ) = 0 isprint( ) = 0 isgraph( ) = 0
15 Exemplo Indicar cadeia; EOF para terminar: abcdefghijklmnop cadeia lida em minusculas: abcdefghijklmnop cadeia lida em maiusculas: ABCDEFGHIJKLMNOP Indicar cadeia; EOF para terminar: a1234ghip+*lmop12 cadeia lida em minusculas: a1234ghip+*lmop12 cadeia lida em maiusculas: A1234GHIP+*LMOP12 Indicar cadeia; EOF para terminar:
#include <stdio.h> /* string2.doc */ #include <ctype.h> void visuminus(char *); void visumaius(char *); main() { char cadeialida[80]; /* não fazer *cadeialida... */ printf("indicar cadeia; EOF para terminar: "); while (NULL!= gets(cadeialida)){ }... printf("cadeia lida em minusculas:\n"); visuminus(cadeialida); printf("cadeia lida em maiusculas:\n"); visumaius(cadeialida); printf("indicar cadeia; EOF para terminar: "); NULL qdo não há caracteres lidos
void visuminus(char *cadeia) { char tempchar; for( ; tempchar = *cadeia; cadeia++) putchar(tolower(tempchar)); putchar('\n'); } void visumaius(char *cadeia) { char tempchar; for( ;tempchar = *cadeia; cadeia++) putchar(toupper(tempchar)); putchar('\n'); }
18 Caracteres e cadeia de caracteres Funções de conversão de cadeias de caracteres #include <stdlib.h> double atof(const char *nptr) converte a cadeia apontada por nptr para double int atoi(const char *nptr) converte a cadeia apontada por nptr para int long atol(const char *nptr) converte a cadeia apontada por nptr para long int ** double strtod(const char *nptr, char **endptr) converte a cadeia apontada por nptr para double, ficando endptr a apontar o 1º caracter não convertido
19 Caracteres e cadeia de caracteres Funções de conversão de cadeias de caracteres #include <stdlib.h> (cont.)... double valor; char *cadeia = 534.2 e uma cadeia, *apontacadeia; &apontador!!! valor = strtod(cadeia, &apontacadeia); printf( O valor double: %.2f\n, valor); printf( A cadeia restante: %s\n, apontacadeia);... O valor double: 534.20 A cadeia restante: e uma cadeia
#include <stdio.h> /* ptrptr.cpp */ #include <stdlib.h> #include <ctype.h> void maiusculas(char *); void minusculas(char **); main() { char *letras1 = "abcdefg", *letras2 = "tuvwxyz", *aponta1, *aponta2; aponta1 = letras1; aponta2 = letras2; printf("letras1 = %s\t*aponta1 = %c\n", letras1, *aponta1); maiusculas(aponta1); printf("depois de maiusculas(aponta1)\n"); printf("letras1 = %s\t*aponta1 = %c\n\n", letras1, *aponta1); printf("letras2 = %s\t*aponta2 = %c\n", letras2, *aponta2); minusculas(&aponta2); printf("depois de minusculas(&aponta2)\n"); printf("letras2 = %s\t*aponta2 = %c\n", letras2, *aponta2);...
void maiusculas(char *nptr) { char tempchar; while(tempchar = *nptr){ *nptr = toupper(tempchar); nptr++; } letras1 = abcdefg *aponta1 = a nptr--; } Depois de maiusculas(aponta1) letras1 = ABCDEFG *aponta1 = A void minusculas(char **nptr) { char tempchar; while(tempchar = **nptr){ **nptr = tolower(tempchar); (*nptr)++; } letras2 = tuvwxyz *aponta2 = t (*nptr)--; Depois de minusculas(&aponta2) } letras2 = tuvwxyz *aponta2 = z
22 Caracteres e cadeia de caracteres Funções de conversão de cadeias de caracteres #include <stdlib.h> (cont.) long strtol(const char *nptr, char **endptr, int base) Converte a cadeia nptr para long, (base 0- o valor contante pode ser na base 8(começa com 0), base 10 ou base 16(começa com 0x); alternativas: base de 2 a 36...), apontando endptr o 1º caracter não convertido unsigned long strtoul(const char *nptr, char **endptr, int base) Converte a cadeia nptr para unsigned long,...
#include <stdio.h> #include <stdlib.h> int main (void) { long valor; char *cadeia1 = "42ab e' uma cadeia", *apontacadeia; char *cadeia2 = "0x42ab e' uma cadeia"; char *cadeia3 = "042ab e' uma cadeia"; char *cadeia4 = "042ab e' uma cadeia"; valor = strtol(cadeia1, &apontacadeia, 0); printf("o valor convertido de cadeia1 e': %ld\n", valor); printf("a cadeia restante: %s\n", apontacadeia); valor = strtol(cadeia2, &apontacadeia, 0); printf("o valor convertido de cadeia2 e': %ld\n", valor); printf("a cadeia restante: %s\n", apontacadeia); valor = strtol(cadeia3, &apontacadeia, 0); printf("o valor convertido de cadeia3 e': %ld\n", valor); printf("a cadeia restante: %s\n", apontacadeia);... valor = strtol(cadeia4, &apontacadeia, 10); printf("o valor convertido de cadeia4 e': %ld\n", valor); printf("a cadeia restante: %s\n", apontacadeia);
Caracteres e cadeia de caracteres Resultado obtido com o programa anterior 24 O valor convertido de cadeia1 e': 42 A cadeia restante: ab e uma cadeia O valor convertido de cadeia2 e': 17067 A cadeia restante: e uma cadeia O valor convertido de cadeia3 e': 34 A cadeia restante: ab e uma cadeia O valor convertido de cadeia4 e': 42 A cadeia restante: ab e uma cadeia
25 Caracteres e cadeia de caracteres Funções de entrada/saída para caracteres e cadeias #include <stdio.h> int getchar (void) Lê o próximo caracter pelo dispositivo de entrada standard e devolve-o como um inteiro char *gets(char *s) Lê caracteres pelo dispositivo de entrada standard e coloca-os no array s até encontrar '\n' ou EOF. NULL, ('\0'), colocado depois do último caracter. Devolução de NULL corresponde a situação anómala.
#include <stdio.h> #include <stdlib.h> int main (void) { char apontacadeia[80], *x; } printf("experiencia: "); x = gets(apontacadeia); printf("%s\n", apontacadeia); printf("%s\n", x); return 0; experiencia: Isto e uma experiencia Isto e uma experiencia Isto e uma experiencia
27 Caracteres e cadeia de caracteres Funções de entrada/saída para caracteres e cadeias #include <stdio.h> (cont.) int putchar(int c) Visualiza caracter colocado em c int puts(const char *s) Visualiza cadeia s seguida de '\n' int sprint(char *s, const char *format,...) Equivalente a printf, mas, em vez de visualizar, coloca em s. Devolve o nº de caracteres lidos. int sscanf(char *s, const char *format,...) Equivalente a scanf, mas, em vez de ler do teclado, lê de s
28 Caracteres e cadeia de caracteres Funções de manipulação de cadeias de caracteres #include <string.h> char *strcpy(char *s1, const char *s2) Copia a cadeia s2 para o array s1. Devolve s1 char *strncpy(char *s1, const char *s2, size_t n) Copia, no máximo, n caracteres de s2 para o array s1. Devolve s1 char *strcat(char *s1, const char *s2) Concatena s2 ao array s1, incluindo o NULL. O primeiro caracter de s2 substitui o NULL de s1. Devolve s1
#include <stdio.h> /* string5.doc */ #include <string.h> main() { char x[] = "Uma experiencia"; char y[25], z[15]; printf("cadeia em x e': %s\n", x); printf("cadeia em y e': %s\n", strcpy(y, x)); x[4] = 'E'; printf("\ncadeia em x e': %s\n", x); printf("cadeia em y e': %s\n", y); strncpy(z, x, 7); z[7] = '\0'; printf("\ncadeia em x... printf("cadeia em z...... Cadeia em x e': Uma experiencia Cadeia em y e': Uma experiencia Cadeia em x e': Uma Experiencia Cadeia em y e': Uma experiencia Cadeia em x e': Uma Experiencia Cadeia em z e': Uma Exp
#include <stdio.h> /* string6.doc */ #include <string.h> main() { char y[9] = "y"; char x[] = "Uma experiencia"; printf("cadeia em x e': %s\n", x); printf("cadeia em y e': %s\n", y); printf("\ncadeia em y e': %s\n", strcpy(y, x)); printf("cadeia em x e': %s\n", x); printf("cadeia em y e': %s\n", y);... Cadeia em x e': Uma experiencia Cadeia em y e': y Cadeia em y e': Uma experiencia Cadeia em x e': cia Cadeia em y e': Uma experiencia Apresentar uma justificação
31 Caracteres e cadeia de caracteres Funções de manipulação de cadeias de caracteres #include <string.h> (cont.) char *strncat(char *s1, const char *s2, size_t n) Concatena, no máximo, n caracteres de s2 ao array s1, completando com NULL. O primeiro caracter de s2 substitui o NULL de s1. Devolve s1 size_t strlen(const char *s) Devolve o número de caracteres de s, excluindo o NULL
32 Caracteres e cadeia de caracteres Funções de comparação de cadeias de caracteres #include <string.h> (cont.) int strcmp(const char *s1, const char *s2) Compara as cadeias s1 e s2. Devolve 0, <0, ou >0 se s1 é igual, menor ou maior, alfabeticamente, que s2 int strncmp(const char *s1, const char *s2, size_t n) Compara até n caracteres das cadeias s1 e s2. Devolve 0, <0, ou >0 se s1 é igual, menor ou maior, alfabeticamente, que s2. Se alguma das cadeias tiver comprimento inferior a n, a comparação vai até ao caracter que precede NULL, da cadeia mais curta.
33 Caracteres e cadeia de caracteres Funções de pesquisa de cadeias de caracteres #include <string.h> (cont.) char *strchr(const char *s, int c) Localiza a primeira ocorrência de c em s. Se c é encontrado, devolve um apontador para esse caracter em s, se não devolve NULL size_t strcspn(const char *s1, const char *s2) Devolve o comprimento da parte inicial de s1 que não contém qualquer caracter de s2 size_t strspn(const char *s1, const char *s2) Devolve o comprimento da parte inicial de s1 constituida apenas por caracteres de s2
34 Caracteres e cadeia de caracteres Funções de pesquisa de cadeias de caracteres #include <string.h> (cont.) char *strpbrk(const char *s1, const char *s2) Localiza em s1 a primeira ocorrência de qualquer caracter de s2. Se um caracter é encontrado, devolve um apontador para esse caracter em s1, se não devolve NULL char *strrchr(const char *s, int c) Localiza em s a última ocorrência de c. Se c é encontrado, devolve um apontador para esse caracter em s, se não devolve NULL char *strstr(const char *s1, const char *s2) Localiza em s1 a primeira ocorrência da cadeia s2. Se a cadeia s2 é encontrada, devolve um apontador para essa cadeia em s1, se não devolve NULL
Caracteres e cadeia de caracteres Funções de pesquisa de cadeias de caracteres 35 #include <string.h> (cont.) char *strtok(char *s1, const char *s2) Parte uma cadeia de caracteres em tokens. O separador de tokens é qualquer um dos caracteres de s2 (espaços, caracteres de pontuação,...). Por exemplo, numa frase, as palavras são os tokens e os separadores de tokens são os espaços que separam as palavras. A primeira chamada de strtok tem como argumentos a cadeia a partir em tokens e a cadeia que define o separador. Nas chamadas seguintes, o primeiro argumento é substituido por NULL. Em cada chamada é salvo um apontador para o próximo token, é devolvido um apontador para o token identificado e os separadores de tokens substituidos por '\0'
Caracteres e cadeia de caracteres Exemplo de utilização de strtok 36 #include <stdio.h> #include <string.h> main (void) { char *cadeia1 = "abc def gh,ijkl; mnop"; char *caractptr; abc def gh ijkl mnop caractptr = strtok (cadeia1, " ;,"); } while(caractptr!= NULL) { printf("%s\n", caractptr); caractptr = strtok(null, " ;,"); } return 0;
Caracteres e cadeia de caracteres Erros mais comuns 37 Não prever espaço num array de caractares, para o NULL Visualizar uma "cadeia" de caracteres que não termina com NULL Processar um caracter (inteiro) como se fosse uma cadeia de caracteres (apontador) Passar um caracter como argumento de uma função, quando a função espera uma cadeia de caracteres... ou vice-versa...
Caracteres e cadeia de caracteres Erros mais comuns 38... Não juntar o NULL ao primeiro argumento de strncpy quando o terceiro argumento é menor ou igual que o comprimento do segundo argumento Assumir que strcmp e strncmp devolve 1 quando os seus argumentos são iguais. Mas, neste caso, é devolvido 0
39 Exercícios Escrever um programa que lê quatro cadeias de caracteres que representam inteiros, converte-as em inteiros, soma os respectivos valores e visualiza o total Escrever um programa que lê uma linha de texto, separa as palavras com a função strtok, e visualiza-as na ordem inversa da entrada, uma em cada linha.
40 Exercícios Escrever um programa que lê uma linha de texto e um caracter. Depois determina e visualiza o número de ocorrências desse caracter na linha, com a função strchr. Escrever um programa que lê uma linha de texto e uma cadeia de caracteres. Depois determina e visualiza o número de ocorrências dessa cadeia na linha, com a função strstr. Exemplo: Linha: Abadadag e uim mais ou nunca!! Cadeia: ada Número de ocorrências: 1
41 Exercícios Escrever um programa que lê várias linhas de texto e determina, com a função strchr, o número de ocorrências das letras do alfabeto (minúsculas e maiúsculas). A visualização será do tipo: a: 334 b: 13 c: 78 d: 6... A: 12 B: 3...
#include <stdio.h> #include <string.h> void palavrasordeminv(char *); main() { char cadeia[60]; char *apontatoken; printf("cadeia: "); gets(cadeia); apontatoken = strtok(cadeia, " "); /* salva um apontador para o próximo caracter, que segue o separador do primeiro token... e devolve um apontador para o primeiro token */ palavrasordeminv(apontatoken); } return 0;
void palavrasordeminv(char *aponta) { if (aponta!= NULL){ palavrasordeminv(strtok(null, " ")); printf("%s\n", aponta); } }