1 Capítulo 8 - Caracteres e Strings 2000 Prentice Hall, Inc. All rights reserved. 2 Capítulo 8 - Caracteres e Strings Sumário 8.1 8.2 8.3 8.4 8.5 8.6 8.7 8.8 8.9 8.10 Introdução Conceitos Fundamentais de Strings e Caracteres Biblioteca de Manipulação de Caracteres Funções de Conversão de Strings Funções da Biblioteca-padrão de Entrada/Saída Funções de Manipulação de Strings da Biblioteca de Manipulação de Strings Funções de Comparação da Biblioteca de Manipulação de Strings Funções de Pesquisa da Biblioteca de Manipulação de Strings Funções de Memória da Biblioteca de Manipulação de Strings Outras Funções da Biblioteca de Manipulação de Strings 2000 Prentice Hall, Inc. All rights reserved. 3 8.1 Introdução • Apresenta algumas funções da biblioteca-padrão – Processamento fácil de strings e caracteres – Programas podem processar caracteres, strings, linhas de texto, e blocos de memória • Estas técnicas são usadas para fazer – Processadores de palavras – Software de formatação de página – Programas editores de texto 2000 Prentice Hall, Inc. All rights reserved. 4 8.2 Conceitos Fundamentais de Strings e Caracteres • Caracteres – Construindo blocos de programas • Todo programa é uma seqüência de caracteres significativos agrupados – Constante caractere • Um valor int representado como um caractere entre apóstrofos • 'z' representa o valor inteiro de z • Strings – Série de caracteres tratada como uma única unidade • Podem incluir letras, dígitos e caracteres especiais (*, /, $) – Literal string (constante string) – escrita entre aspas • "Hello" – Strings são arrays de caracteres • String é um apontador para o primeiro caractere • Valor de um string é o endereço do primeiro caractere 2000 Prentice Hall, Inc. All rights reserved. 5 8.2 Conceitos Fundamentais de Strings e Caracteres • Declarações de String – Declare como um array de caracteres ou uma variável de tipo char * char cor[] = “azul"; char *corPtr = “azul"; – Lembre-se que strings representados como arrays de caracteres terminam com '\0' • cor tem 5 elementos • Entrando com strings – Uso de scanf scanf("%s", palavra); • Copia a entrada para palavra[] • Não necessita & (porque um string é um apontador) – Uso de gets: gets(palavra); 2000 Prentice Hall, Inc. All rights reserved. 6 8.3 Biblioteca de Manipulação de Caracteres • Biblioteca de manipulação de caracteres – Inclui funções para realizar testes úteis e manipulações de dados caracteres – Cada função recebe um caractere (um int) ou EOF como um argumento • O slide seguinte contém uma tabela de todas as funções em <ctype.h> • Note que vale: – Verdadeiro = número positivo – Falso =0 2000 Prentice Hall, Inc. All rights reserved. 7 8.3 Biblioteca de Manipulação de Caracteres Protótipo Descrição int isdigit( int c ) Retorna verdadeiro se c é um dígito e falso caso contrário. int isalpha( int c ) Retorna verdadeiro se c é um letra e falso caso contrário. int isalnum( int c ) Retorna verdadeiro se c é um dígito or uma letra e falso caso contrário. int isxdigit( int c ) Retorna verdadeiro se c é um caractere dígito hexadecimal e falso caso contrário. int islower( int c ) Retorna verdadeiro se c é uma letra minúscula e falso caso contrário. int isupper( int c ) Retorna verdadeiro se c é uma letra maiúscula; falso caso contrário. int tolower( int c ) Se c é auma letra maiúscula, tolower retorna c como uma letra minúscula. Caso contrário, tolower retorna o argumento sem modificação. int toupper( int c ) Se c é uma letra minúscula, toupper retorna c como uma letra maiúscula. Caso contrário, toupper retorna o argumento sem modificação. int isspace( int c ) Retorna verdadeiro se c é um caractere espaço em branco—nova-linha ('\n'), espaço (' '), form feed ('\f'), carriage return ('\r'), tab horizontal ('\t'), or tab vertical ('\v')—e falso caso contrário int iscntrl( int c ) Retorna verdadeiro se c é um caractere de controle e falso caso contrário. int ispunct( int c ) Retorna verdadeiro se c é um caractere de impressão diferente de um espaço, um dígito, or uma letra e falso caso contrário. int isprint( int c ) Retorna o valor verdadeiro se c é um caractere de impressão, incluindo espaço (' ') e falso caso contrário. int isgraph( int c ) Retorna verdadeiro se c é um caractere de impressão diferente de um espaço (' ') e falso caso contrário. 2000 Prentice Hall, Inc. All rights reserved. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 /* Fig. 8.2: fig08_02.c Usando as funções isdigit, isalpha, isalnum, and isxdigit */ #include <stdio.h> #include <ctype.h> int main() { printf( "%s\n%s%s\n%s%s\n\n", “De acordo com isdigit: ", isdigit( '8' ) ? "8 é um " : "8 não é um ", "dígito", isdigit( '#' ) ? "# é um " : "# não é um ", " dígito" ); printf( "%s\n%s%s\n%s%s\n%s%s\n%s%s\n\n", “De acordo com isalpha:", isalpha( 'A' ) ? "A é uma " : "A não é uma ", “letra", isalpha( 'b' ) ? "b é uma " : "b não é uma ", "letra", isalpha( '&' ) ? "& é uma " : "& não é uma ", "letra", isalpha( '4' ) ? "4 é uma " : "4 não é uma ", “letra" ); printf( "%s\n%s%s\n%s%s\n%s%s\n\n", “De acordo com isalnum:", isalnum( 'A' ) ? "A é um " : "A não é um ", “dígito ou uma letra", isalnum( '8' ) ? "8 é um " : "8 não é um ", “dígito ou uma letra", isalnum( '#' ) ? "# é um " : "# não é um ", "dígito ou uma letra" ); printf( "%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n", "De acordo com isxdigit:", isxdigit( 'F' ) ? "F é um " : "F não é um ", “dígito hexadecimal", isxdigit( 'J' ) ? "J é um " : "J não é um ", “dígito hexadecimal", 8 Outline 1. Carrega cabeçalho 2. Realiza testes 3. Imprime 2000 Prentice Hall, Inc. All rights reserved. 33 isxdigit( '7' ) ? "7 é um " : "7 não é um ", 34 “dígito hexadecimal", 35 isxdigit( '$' ) ? "$ é um " : "$ não é um ", 36 “dígito hexadecimal", 37 isxdigit( 'f' ) ? "f é um " : "f não é um ", 38 “dígito hexadecimal" ); 39 9 Outline 3. Impressão return 0; 40 } De acordo com isdigit: 8 é um dígito # não é um dígito Saída do programa De acordo com isalpha: A é uma letra b é uma letra & não é uma letra 4 não é uma letra De acordo com isalnum: A é um dígito ou uma letra 8 é um dígito ou uma letra # não é um dígito ou uma letra De acordo com isxdigit: F é um dígito hexadecimal J não é um dígito hexadecimal 7 é um dígito hexadecimal $ não é um dígito hexadecimal f é um dígito hexadecimal 2000 Prentice Hall, Inc. All rights reserved. 10 8.4 Funções de Conversão de String • Funções de Conversão – Em <stdlib.h> (biblioteca geral de utilitários) • Converte strings de dígitos em valores inteiros ou de ponto flutuante Protótipo Descrição double atof( const char *nPtr ) Converte o string nPtr em double. int atoi( const char *nPtr ) Converte o string nPtr em int. long atol( const char *nPtr ) Converte o string nPtr em long int. double strtod( const char *nPtr, char **endPtr ) long strtol( const char *nPtr, char **endPtr, int base ) unsigned long strtoul( const char *nPtr, char **endPtr, int base ) Converte o string nPtr em double. Converte o string nPtr em long. Converte o string nPtr em unsigned long. 2000 Prentice Hall, Inc. All rights reserved. 1 /* Fig. 8.6: fig08_06.c 2 Usando atof */ 3 #include <stdio.h> 4 #include <stdlib.h> 11 Outline 1. Inicializa variável 5 6 int main() 7 { 8 2. Converte string double d; 2.1 Atribui à variável 9 10 d = atof( "99.0" ); 11 printf( "%s%.3f\n%s%.3f\n", 12 “O string \"99.0\" convertido em double is ", d, 13 “O valor convertido dividido por 2 é ", 14 d / 2.0 ); 15 3. Imprime return 0; 16 } O string "99.0" convertido em double is 99.000 O valor convertido dividido por 2 é 49.500 Saída do programa 2000 Prentice Hall, Inc. All rights reserved. 12 8.5 Funções da Biblioteca-padrão de Entrada/Saída • Funções em <stdio.h> – Usadas para manipular caracteres e dados string Protótipo da função int getchar( void ); Descrição da Função int putchar( int c ); Obtém o próximo caractere do dispositivo-padrão de entrada e o retorna como um inteiro. Obtém caracteres do dispositivo-padrão de entrada para dentro de um array s até que um caractere nova-linha ou fim-dearquivo seja encontrado. Um caractere terminal null é adicionado ao array. Imprime o caractere armazenado em c. int puts( const char *s ); Imprime o string s seguido pelo caractere nova-linha. int sprintf( char *s, const char *format, ... ); Equivalente ao printf, exceto que a saída é armazenada no array s em vez de impressa na tela. int sscanf( char *s, const char *format, ... ); Equivalente ao scanf, exceto que a entrada é lida do array s em vez de ser lida do teclado. char *gets( char *s ); 2000 Prentice Hall, Inc. All rights reserved. 1 /* Fig. 8.13: fig08_13.c 13 2 Usando gets e putchar */ 3 #include <stdio.h> 4 5 int main() 1. Inicializa variáveis 6 { 7 char sentenca[ 80 ]; 2. Entra 8 void reverse( const char * const ); 9 10 printf( “Entre com uma linha de texto:\n" ); 3. Imprime 11 gets( sentenca ); 12 13 printf( "\nA linha impressa na ordem inversa é:\n" ); 3.1 Definição da 14 reverse( sentenca ); função (note a 15 recursividade) 16 return 0; 17 } 18 19 void reverse( const char * const sPtr ) 20 { 21 if ( sPtr[ 0 ] == '\0' ) reverse chama a si própria usando 22 return; substrings do string original. Quando ela 23 else { alcança o caractere '\0' imprime usando 24 reverse( &sPtr[ 1 ] ); 25 putchar( sPtr[ 0 ] ); putchar 26 } 27 } Entre com uma linha de texto: Caracteres e Strings Outline A linha impressa na ordem inversa é: sgnirtS dna seretcaraC Saída do programa 2000 Prentice Hall, Inc. All rights reserved. 14 8.6 Funções de Manipulação de Strings da Biblioteca de Manipulação de Strings • A biblioteca de manipulação de strings (<string.h>) tem funções para – Manipular dados string – Pesquisar strings – Separar partes de strings Protótipo da funçãotamanho deDescrição – Determinar string da função char *strcpy( char *s1, const char *s2 ) Copia o string s2 para o array s1. O valor de s1 é retornado. char *strncpy( char *s1, Copia no máximo n caracteres do string s2 para o const char *s2, size_t n array s1. O valor de s1 é retornado. ) char *strcat( char *s1, Anexa o string s2 ao array s1. O primeiro caractere de const char *s2 ) s2 sobrepõe o caractere terminal null de s1. O valor de s1 é retornado. char *strncat( char *s1, Anexa no máximo n caracteres do string s2 ao array const char *s2, size_t n s1. O primeiro caractere de s2 sobrepões o caractere ) terminal null de s1. O valor de s1 é retornado. 2000 Prentice Hall, Inc. All rights reserved. 1 /* Fig. 8.19: fig08_19.c 2 Usando strcat e strncat */ 3 #include <stdio.h> 4 #include <string.h> 15 Outline 1. Inicializa variáveis 5 6 int main() 7 { 8 char s1[ 20 ] = “Feliz "; 9 char s2[] = “Ano Novo "; 10 2. Chama funções 3. Imprime char s3[ 40 ] = ""; 11 12 printf( "s1 = %s\ns2 = %s\n", s1, s2 ); 13 printf( "strcat( s1, s2 ) = %s\n", strcat( s1, s2 ) ); 14 printf( "strncat( s3, s1, 6 ) = %s\n", strncat( s3, s1, 6 ) ); 15 printf( "strcat( s3, s1 ) = %s\n", strcat( s3, s1 ) ); 16 return 0; 17 } s1 = Feliz s2 = Ano Novo strcat( s1, s2 ) = Feliz Ano Novo strncat( s3, s1, 6 ) = Feliz strcat( s3, s1 ) = Feliz Feliz Ano Novo Saída do programa 2000 Prentice Hall, Inc. All rights reserved. 16 8.7 Funções de Comparação da Biblioteca de Manipulação de Strings • Comparando strings – O computador compara o código numérico ASCII dos caracteres no string – Apêndice D tem uma lista dos código dos caracteres int strcmp( const char *s1, const char *s2 ); – Compara o string s1 com o s2 – Retorna um número negativo se s1 < s2, zero se s1 == s2 ou um número positivo se s1 > s2 int strncmp( const char *s1, const char *s2, size_t n ); – Compara até n caracteres do string s1 com o string s2 – Retorna valores como acima 2000 Prentice Hall, Inc. All rights reserved. 17 8.8 Funções de Pesquisa da Biblioteca de Manipulação de Strings Protótipo da Função Descrição da Função char *strchr( const char *s, int c ); Localiza a primeira ocorrência do caractere c no string s. Se c é encontrado, um apontador para c in s é retornado. Caso contrário, um apontador NULL é retornado. size_t strcspn( const char Determina e retorna o tamanho do segmento inicial do s1 que consiste de caracteres *s1, const char *s2 ); não contidos no string s2. size_t strspn( const char *s1, const char *s2 ); Determina e retorna o tamanho do segmento inicial do string s1 que consiste só de caracteres contidos no string s2. char *strpbrk( const char *s1, const char *s2 ); Localiza a primeira ocorrência no s1 de qualquer caractere no string s2. Se um caractere do string s2 é encontrado, um apontador para o caractere em string s1 é retornado. Caso contrário, um apontador NULL é retornado. char *strrchr( const char *s, int c ); Localiza a última ocorrência de c no string s. Se c é encontrado, um apontador para c no string s é retornado. Caso contrário, um apontador NULL é retornado. char *strstr( const char *s1, const char *s2 ); Localiza a primeira acorrência no string s1 do string s2. Se o string é encontrado, um apontador para o string in s1 é retornado. Caso contrário, um apontador NULL é retornado. char *strtok( char *s1, const char *s2 ); Uma seqüência de chamadas a strtok divide o string s1 em “tokens”—trechos lógicos, como palavras em uma linha de texto—separados por caracteres contidos no string s2. A primeira chamada contém s1 como o primeiro argumento, e as chamadas subseqüentes pa continuar dividindo o mesmo string contém NULL como o primeiro argumento. Um apontador para o token corrente é retornado por cada chamada. Se não existir mais tokens quando a função for chamada, NULL é retornado. 2000 Prentice Hall, Inc. All rights reserved. 1 /* Fig. 8.27: fig08_27.c 2 3 Usando strspn */ 18 Outline #include <stdio.h> 4 #include <string.h> 1. Inicializa variáveis 5 6 int main() 7 { 2. Chama funções 8 const char *string1 = “O valor é 3.14159"; 9 const char *string2 = "aeoi lsOrv"; 3. Imprime 10 11 printf( "%s%s\n%s%s\n\n%s\n%s%u\n", 12 "string1 = ", string1, "string2 = ", string2, 13 “O tamanho do segmento inicial de string1", 14 "contendo só caracteres do string2 = ", 15 strspn( string1, string2 ) ); 16 return 0; 17 } string1 = O valor é 3.14159 string2 = aeoi lsOrv Saída do programa O tamanho do seguimento inicial de string1 Contendo só caracteres de string2 = 7 2000 Prentice Hall, Inc. All rights reserved. 1 /* Fig. 8.29: fig08_29.c 2 Usando strtok */ 3 #include <stdio.h> 4 #include <string.h> 5 6 int main() 7 { 8 char string[] = “Esta é uma frase com 7 tokens"; 9 char *tokenPtr; 10 11 printf( "%s\n%s\n\n%s\n", 12 “O string a ser dividido é:", string, 13 “Os tokens são:" ); 14 15 tokenPtr = strtok( string, " " ); 16 17 while ( tokenPtr != NULL ) { 18 printf( "%s\n", tokenPtr ); 19 tokenPtr = strtok( NULL, " " ); 20 } 21 22 return 0; 23 } O string a ser dividido é: Esta é uma frase com 7 tokens Os tokens são: Esta É Uma Frase Com 7 tokens 19 Outline 1. Inicializa variáveis 2. Chama funções 3. Imprime Saída do programa 2000 Prentice Hall, Inc. All rights reserved. 20 8.9 Funções de Memória da Biblioteca de Manipulação de Strings • Funções de memória – Em <stdlib.h> – Manipulam, comparam, e pesquisam blocos de memória – Podem manipular qualquer bloco de dados • Parameters apontadores são void * – Qualquer apontador pode ser atribuído a void *, e vice versa – void * não pode ser desreferenciado • Cada função recebe um tamanho como argumento, especificando o número de bytes (caracteres) a processar 2000 Prentice Hall, Inc. All rights reserved. 21 8.9 Memory Functions of the Stringhandling Library Protótipo Descrição void *memcpy( void *s1, const void *s2, size_t n ) Copia n caracteres do objeto apontado por s2 para o objeto apontado por s1. É retornado um apontador para o objeto resultante. void *memmove( void *s1, Copia n caracteres do objeto apontado por s2 para o objeto const void *s2, apontado por s1. A cópia é realizada como se os caracteres size_t n ) fossem copiados primeiramente do objeto apontado por s2 para um array temporário, e então copiado do array temporário para o objeto apontado por s1. É retornado um apontador para o objeto resultante. int memcmp( const void *s1, Compara os primeiros n caracteres dos objetos apontados por s1 const void *s2, e s2. A função retorna 0, menor que 0, ou maior que 0 se s1 é size_t n ) igual a, menor que ou maior que s2, respectivamente. void *memchr(const void *s, Localiza a primeira ocorrência de c (convertido para unsigned int c, size_t n ) char) nos primeiros n caracteres do objeto apontado por s. Se c é encontrado, um apontador para c no objeto é retornado. Caso contrário, 0 é retornado. void *memset( void *s, Copia c (convertido para unsigned char) para os primeiros n int c, size_t n ) caracteres do objeto apontado por s. É retornado um apontador para o resultado. 2000 Prentice Hall, Inc. All rights reserved. 1 /* Fig. 8.32: fig08_32.c 2 Usando memmove */ 3 #include <stdio.h> 4 #include <string.h> 22 Outline 1. Inicializa variáveis 5 6 int main() 7 { 8 2. Chama funções char x[] = “Lar Doce lar"; 9 10 11 12 3. Imprime printf( "%s%s\n", “O string no array x antes de memmove é: ", x ); printf( "%s%s\n", 13 “O string no array x depois de memmove é: 14 memmove( x, &x[ 4 ], 8 ) ); ", 15 16 return 0; 17 } O string no array x antes de memmove é: Lar Doce Lar O string no array x depois de memmove é: Doce Lar Lar Saída do programa 2000 Prentice Hall, Inc. All rights reserved. 23 8.10 Outras funções da Biblioteca de Manipulação de Strings • char *strerror( int errornum ); – Cria uma mensagem de erro dependente do sistema baseada em errornum – Retorna uma apontador para o string • size_t strlen( const char *s ); – Retorna o número de caracteres (antes do NULL) no string s 2000 Prentice Hall, Inc. All rights reserved. 1 /* Fig. 8.37: fig08_37.c 2 Usando strerror */ 3 #include <stdio.h> 4 #include <string.h> 5 6 24 Outline 1. Chama função 2. Imprime int main() 7 { 8 printf( "%s\n", strerror( 2 ) ); 9 return 0; 10 } Error 2 Saída do programa 2000 Prentice Hall, Inc. All rights reserved.