Programação II. Strings (Cadeias de Caracteres) Bruno Feijó Dept. de Informática, PUC-Rio

Documentos relacionados
Programação II. Strings (Cadeias de Caracteres) Bruno Feijó Dept. de Informática, PUC-Rio

Programação de Computadores II. Cap. 7 Cadeias de Caracteres

Programação de Computadores II. Cap. 7 Cadeias de Caracteres 1/2

Módulo 7 Cadeias de Caracteres

Cadeias de Caracteres (Strings)

Caracteres e Cadeias de Caracteres

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

Programação II. Strings (Cadeias de Caracteres) Bruno Feijó Dept. de Informática, PUC-Rio

cadeia de caracteres (string) INF Programação I Prof. Roberto Azevedo

Tratamento de Caracteres

INF 1005 Programação I

Estruturas de Dados. Profa. Juliana Pinheiro Campos

Referências. Programação de Computadores II. Cap. 7 Cadeias de Caracteres. Caracteres. Tópicos

3.1 - Funções para manipular dados de entrada e saída padrão

Estruturas de Dados Aula 6: Cadeias de 28/03/2010

Estruturas de Dados Aula 6: Cadeias de Caracteres

Introdução a Programação. Strings (Vetor de Caracteres)

Métodos Computacionais. Strings (Vetor de Caracteres)

3 Cadeias de Caracteres

Computação Eletrônica. Strings. Prof: Luciano Barbosa. CIn.ufpe.br

INF 1007 Programação II

6. Cadeia de caracteres

Char e Strings de Caracteres

PROGRAMAÇÃO I E N T R A DA E S A Í DA D E DA D O S

Char e Strings de Caracteres

Programação II. Vetores e Alocação Dinâmica. Bruno Feijó Dept. de Informática, PUC-Rio

Estruturas da linguagem C. 1. Identificadores, tipos primitivos, variáveis e constantes, operadores e expressões.

Linguagem C Parte 4 - Extra

Aula 3 Constantes e funções de E/S

Apêndice B. Cadeias de Caracteres (Strings)

Aula 9 Oficina de Programação Strings. Profa. Elaine Faria UFU

Programação II. Vetores e Alocação Dinâmica. Bruno Feijó Dept. de Informática, PUC-Rio

LINGUAGEM C: ARRAYS DE CARACTERES: STRINGS

Vetores. Vetores. Vetores. Vetores. Vetores. Algoritmos e Lógica de Programação. Vetores

Introdução a Programação de Jogos

INTRODUÇÃO À LINGUAGEM C

INTRODUÇÃO À LINGUAGEM C

Capítulo 1: Introdução à Linguagem C. Pontifícia Universidade Católica Departamento de Informática

Computação 2. Aula 3. Diego Addan Vetores de caracteres (strings)

CURSO BÁSICO DE PROGRAMAÇÃO AULA 11. Revisão Aula Anterior Vetores Cadeia de Caracteres

3. Linguagem de Programação C

Vetores II. Strings Leitura e exibição Biblioteca string.h Operações com Strings. Matrizes Definição de Acesso Operações com Matrizes

ECT1203 Linguagem de Programação

3. Linguagem de Programação C

Programação de Computadores I Funções Básicas da Linguagem C PROFESSORA CINTIA CAETANO

Linguagem C. André Tavares da Silva.

Métodos Computacionais em Física

Curso Básico de Programação Aula 11. Revisão Aula Anterior Laços de Repetição While; Do-While; For.

Programação II. Vetores Bidimensionais e Vetores de Ponteiros. Bruno Feijó Dept. de Informática, PUC-Rio

INTRODUÇÃO À LINGUAGEM C

Linguagem de Programação C

LINGUAGEM DE PROGRAMAÇÃO C AULA 2. Professor: Rodrigo Rocha

LINGUAGEM C: VARIÁVEIS E EXPRESSÕES

Estruturas de Dados. Módulo 2 Expressões. 9/8/2005 (c) Marco A. Casanova - PUC-Rio 1

Estrutura de Dados. Cadeia de Caracteres. Roberto Araujo Ago/2013

Funções de Entrada e Saída

Introdução à Programação

1 Exercícios com ponteiros

CURSO BÁSICO DE PROGRAMAÇÃO AULA 15. Revisão Vetores e Matrizes Trabalho

1 Exercícios com ponteiros

Linguagem C: Introdução

J. L. Rangel 1. Escreva um programa em C que lê três números inteiros do teclado, e imprime os três números em ordem crescente.

Introdução à Ciência da Computação scc-120

INSTITUTO FEDERAL DE! EDUCAÇÃO, CIÊNCIA E TECNOLOGIA RIO GRANDE DO NORTE

Estruturas de Dados. Introdução Definição de Ponteiros Declaração de Ponteiros em C Manipulação de Ponteiros em C

Programação II. Listas Encadeadas (Linked Lists) Bruno Feijó Dept. de Informática, PUC-Rio

Disciplina de Algoritmos e Programação

Computadores Digitais 2. Prof. Rodrigo de Souza Couto

Índice Valor C A D E I A \0 memória

Programação Estruturada Prof. Rodrigo Hausen Organização e Gerenciamento de Memória

Programação II. Ordenação (sort) Bruno Feijó Dept. de Informática, PUC-Rio

Programação I A Linguagem C. Prof. Carlos Alberto

Aula 3:Introdução à Linguagem C

Fundamentos de Programação. Linguagem C++ aula II - Variáveis e constantes. Prof.: Bruno Gomes

Algoritmos e Programação

Programação de Computadores I

Laboratório de Programação II

Programação: Vetores

O que é um apontador em C (type pointer in C)?

Hello World. Linguagem C. Tipos de Dados. Palavras Reservadas. Operadores Aritméticos. Pré e pós incremento e pré e pós decremento

Introdução à Linguagem C Variáveis e Expressões

Introdução a Computação

Linguagem C Entrada/Saída (console)

Faculdade de Computação

Programação II. Vetor de Tipo Estruturado e Vetor de Ponteiros. Bruno Feijó Dept. de Informática, PUC-Rio

Ponteiros e Alocação de Memória

INF1007: Programação 2. 0 Revisão. 06/08/2015 (c) Dept. de Informática - PUC-Rio 1

Sumário. Introdução à Ciência da Computação. Ponteiros em C. Introdução. Definição. Por quê ponteiros são importantes?

CURSO SUPERIOR DE TECNOLOGIA EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS DISCIPLINA : INTRODUÇÃO À LÓGICA DE PROGRAMAÇÃO ASSUNTO: C

Strings. Introdução. Definição de strings. Criação/Declaração de strings. Inicialização de strings. Manipulação de strings. Exemplos.

Disciplina de Algoritmos e Programação

Comandos de entrada. e saída. Comandos de entrada. Comandos de entrada. Comandos de entrada. Comandos de entrada. Comandos de entrada.

Linguagem C Princípios Básicos (parte 1)

A Linguagem C. A forma de um programa em C

Mais sobre Ponteiros em C

Ponteiros e Tabelas. K&R: Capítulo 5

Programação I Matrizes e Strings. Prof. Carlos Alberto

Introdução à Programação em C Input / Output

Transcrição:

Programação II Strings (Cadeias de Caracteres) Bruno Feijó Dept. de Informática, PUC-Rio

Caracteres tipo char: tamanho de char = 1 byte = 8 bits = 256 valores distintos tabela de códigos: define correspondência entre caracteres e códigos numéricos exemplo: ASCII alguns alfabetos precisam de maior representatividade... alfabeto chinês tem mais de 256 caracteres!

Caracteres Código ASCII Códigos ASCII de alguns caracteres: space 0 1 2 3 4 5 6 7 8 9 30 rs us sp! " # $ % & ' 40 ( ) * +, -. / 0 1 50 2 3 4 5 6 7 8 9 : ; 60 < = >? @ A B C D E 70 F G H I J K L M N O 80 P Q R S T U V W X Y 90 Z [ \ ] ^ _ ` a b c 100 d e f g h i j k l m 110 n o p q r S t u v w 120 x y z ~ del Exemplo: o código de 0 é 48... e o número 0 representa o quê? 82 105 111 32 100 101 32 74 97 110 101 105 114 111 R i o d e J a n e i r o Em 1963, havia apenas letras maiúsculas e números. Em 1967, adicionaram letras minúsculas e caracteres de controle (indo de 0 a 127). Em 1981, a IBM (para o primeiro IBM-PC) adicionou mais 128 caracteres (Extended Characters), principalmente para permitir textos em outros idiomas, novos sinais gráficos e símbolos. Por exemplo: Ç (128), é (130), ½ (171), (168),.... Para exibir usando o teclado: Alt+número. 0 a 31 são caracteres de controle (não imprimem), e.g. null (0), Bell (9), tab horizontal (9),....

Caracteres códigos de controle Códigos ASCII de alguns caracteres de controle No. Código Nome: descrição White Spaces em C 0 nul null: nulo \0 7 bel bell: campainha \a 8 bs backspace: volta e apaga um caractere 9 ht tab: tabulação horizontal \t 10 nl newline ou line feed: muda de linha \n 13 cr carriage return: volta ao início da linha 127 del delete: apaga um caractere \b escape sequences são também chamados de white spaces porque eles não são exibidos na tela Em C, o código 10, na realidade, muda de linha e vai para o início. O código 13 apenas volta para o início. O seguinte trecho de programa: char n = 10; char c = 13; printf("abcdef%cghij%c,,\n",n,c); imprime: abcdef,,ij

Constante de Caractere Constante de caractere: É um caractere envolvido com aspas simples: a, 0,... exemplo: 'a' representa uma constante de caractere 'a' resulta no valor numérico associado ao caractere a char c = 'a'; printf("%d %c\n", c, c); printf imprime o conteúdo da variável c usando dois formatos: com o formato para inteiro, %d, imprime 97 com o formato de caractere, %c, imprime a (código 97 em ASCII)

Exercício Conversão de Caractere para Maiúscula int toupper(int c) converte c em letra maiúscula. Requer <ctype.h>. Implemente a sua versão int paramaiuscula(int c): int paramaiuscula(int c) if (c >= 'a' && c <= 'z') // verifica se e minuscula c = (c - 'a') + 'A'; // converte return c;

Vetor (array) de caracteres Exemplo de um vetor de 3 caracteres char a[3]; a[0] = 'p'; a[1] = 'u'; a[2] = 'c'; Os elementos do vetor estão em endereços contíguos de memória a p u c a Podemos definir um ponteiro para um vetor char * p; p = &a[0]; 101 102 103 ou char * p; p = a; char a[3] = 'p','u','c'; Note que *p, *(p+1) e *(p+2) são os valores p, u e c ou endereços a é o mesmo que &a[0], i.e. o endereço do 1o. elemento Qualquer expressão [] pode ser escrita com a sintaxe +. Portanto, são equivalentes: *(p+2) p[2] *(a+2) a[2] p++; está correto, mas a++; e a = p; não!! (pois nome de vetor é um ponteiro constante e não pode ser alterado) (equivale a: char * const a;) Defina void f(char * a) ao invés de void f(char a[]) p p u c 101 102 103

String (Cadeia de Caracteres) Um string é um vetor de caracteres com um terminador o terminador é o caractere '\0' cujo valor numérico é 0 maneiras de definir um string: como array: char a[4] = 'p','u','c','\0'; ou char a[] = "puc"; usando ponteiro: Na memória: a p u como array: c \0 201 202 203 204 char * a = "puc"; usando ponteiro: OBS: se você usar printf("abcdef\0gh\n"); a impressão ignora g, h e \n: abcdef Lembre que a sintaxe [] faz a aritmética de endereço para você, i.e. multiplica o índice pelo tamanho do elemento, soma o offset em bytes e dereferencia o ponteiro resultante para pegar o valor desejado: a[2] *(a+2). Escrever funções que manipulam strings é basicamente passear com o ponteiro e interromper quando o terminador é encontrado. Veja o exemplo a seguir. a p u c \0 201 202 203 204

Strings Exemplo de função strlen Escreva a função strlen que retorna o comprimento de um string: int strlen(char * s) // calcula comprimento de um string int n; O teste *s!= '\0' é uma expressão for (n=0; *s!= '\0'; s++) booleana (que retorna 0 se falso e diferente n++; de zero se verdadeiro). Portanto, lembrando return n; que o único caractere que tem valor zero é o terminador \0, basta verificar diretamente o valor de *s, isto é: for (n=0; *s; s++) Use while e reescreva strlen da forma mais concisa possível: int strlen(char * s) int n = 0; while (*s++) n++; return n; Se você acha isto estranho, o que você acha que acontece com: if (0) printf( ola ); Resposta: ola nunca será impresso. Troque 0 por 5, -5 ou 2-7 para imprimir o ola. // testa *s e depois incrementa s

Strings Exemplo de função stringcopy Função stringcopy(s,t) que copia t para s. A solução abaixo requer o cuidado de finalizar o s. void stringcopy(char * s, char *t) for(;*t;t++,s++) *s = *t; *s = '\0'; // finaliza s

Strings função stringcopy mais concisa void stringcopy(char * s, char * t) // copia t para s versao 1 while ((*s = *t)!= '\0') s++; t++; ou void stringcopy(char * s, char * t) // copia t para s versao 2 Primeiro copia *t para *s, depois verifica se *s while ((*s++ = *t++)!= '\0') é diferente de \0 e, por fim, incrementa t e s. ; Note que após o while, s está apontando para após o \0, o que não importa para quem ou chamou a função. void stringcopy(char * s, char * t) // copia t para s versao 3 while (*s++ = *t++) ; Note que nestas soluções, o terminador é sempre copiado.

Strings outras soluções para stringcopy void stringcopy(char * s, char * t) while (*t) *s++ = *t++; *s = '\0'; ou void stringcopy(char * s, char * t) do *s++ = *t; while(*t++); As formas deste slide e do slide anterior compilarão para basicamente o mesmo código com a mesma eficiência. Trata-se, muito mais, de uma questão de estilo e de uma maneira própria de falar C de um bom programador. O programador habituado com este estilo e com o uso de ponteiros vai naturalmente escrever programas de melhor qualidade e, portanto, mais eficientes.

Exemplo Converte String para Maiúsculas Destruindo Usando toupper, que converte um único caractere e está em <ctype.h>, escreva uma função strupper1 que converte um string para maiúsculas, destruindo a informação original que estava no string dado. #include <ctype.h> void strupper1(char * s) // destroi s for (;*s;s++) *s= toupper(*s);

Constante de String Constante de cadeia de caracteres: representada por seqüê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

Constante de String... define um string literal (constante de string): char s1[] = "Rio de Janeiro"; s1 é um array (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. String literals são tipicamente armazenados em memória readonly. Assim, se um ponteiro é inicializado com o endereço de um string literal, qualquer tentativa de modificação dá erro de access violation. No primeiro caso, o string literal inicializa o array criando uma cópia do string literal no espaço alocado estaticamente para o array s1.

Strings e Manipulação de Memória int main(void) char a[] = "puc"; char * b = "puc"; char c[] = 'p','u','c','\0'; char * d; char m[4]; char * n = (char *)malloc(4*sizeof(char)); d = a; printf("a=%s b=%s c=%s d=%s\n", a,b,c,d); printf(" b[1]=%c *(b+1)=%c\n",b[1],*(b+1)); a[1] = 'a'; // o que daria: b[1] = 'a'; e *(b+1) = 'a';??? Tente entender os valores das variáveis e dos elementos de vetor neste programa a=puc b=puc c=puc d=puc b[1]=u strcpy(m,b); m[1] = 'a'; strcpy(n,b); n[1] = 'a'; c[1] = 'a'; d[1] = 'a'; a=pac m=pac n=pac c=pac printf("a=%s m=%s n=%s c=%s d=%s\n", a,m,n,c,d); return 0; *(b+1)=u // b[1] = 'a'; // ERRO! // *(b+1) = 'a'; // ERRO! d=pac Obs: a não é uma variável e não poderíamos fazer a++. Mas podemos fazer d++. Note que b é variável.

Biblioteca de Funções de Strings As funções de string requerem #include <string.h> Algumas das funções mais usadas estão listadas abaixo (onde s e t são char *, c é um int convertido para char, e n é int. char * strcpy(s,t) char * strncpy(s,t,n) char * strcat(s,t) char * strncat(s,t,n) char * strcmp(s,t) char * strncmp(s,t,n) char * strchr(s,c) char * strrchr(s,c) char * strstr(s,t) int strlen(s) copia t para s e retorna s copia n caracteres de t para s e retorna s concatena t para o final de s e retorna s concatena n caracteres de t para s e retorna s compara s a t e retorna <0 se s<t, 0 se s==t, e >0 se s>t compara n caracteres de s com t retorna ponteiro para a 1a. ocorrência de c em s (retorna NULL se não encontrar c) retorna ponteiro para a última ocorrência de c em s retorna pointer para 1a. ocorrência do string t em s retorna comprimento de s O tipo int usado acima (e.g. n e strlen) é, na realidade, o tipo size_t. Dependendo da implementação, size_t é unsigned int ou unsigned long. Para uma programação absolutamente segura, ou você faz um cast para unsigned long ou usa o tipo size_t provido pelo <stddef.h>.

Leitura de Caracteres

Leitura de Caracteres e Strings com scanf Especificadores de formato definem o comportamento do scanf scanf com o especificador de formato %c lê o valor de um único caractere fornecido via teclado para pular todos os caracteres brancos antes do caractere: um espaço em branco no formato, antes do especificador Cuidados com scanf char a,b;... scanf("%c",&a); carriage return (\n), assim como qualquer caractere branco (\n, \t,...) é caracter válido e será usado na próxima leitura. Uma solução é usar o fflush para limpar o stream de input (e.g. stdin): char a, b; scanf("%c",&a); scanf("%c",&b); // b ='\n' scanf(" %c",&a); char a, b; scanf("%c",&a); fflush(stdin); scanf("%c",&b); scanf é uma função pesada e mal comportada para caracteres e strings (porém bem comportada para números), o que exige atenção. Para caracteres, há programadores que recomendam getchar (mais leve e rápida). fflush em input stream tem efeito indefinido no ANSI C, ameaçando compatibilidade. Uma alternativa é evitar scanf e fflush para caracteres; neste caso opte por controlar tudo, e.g.: char a; Alternativa pior: scanf(" %c",&b); a = getchar(); while (getchar()!='\n );

Leitura de Caracteres e Strings com scanf cuidados com scanf e formato %c: não pula os caracteres brancos caractere branco = espaço (' '), tabulação ('\t') ou nova linha ('\n') se o usuário teclar um espaço antes da letra: o código do espaço será capturado a letra será capturada apenas na próxima chamada de scanf para pular todos os caracteres brancos antes do caractere: basta incluir um espaço em branco no formato, antes do especificador char a;... scanf(" %c", &a); //branco no formato pula brancos da entrada...

Leitura de Caracteres e Strings com scanf scanf com o especificador de formato %s lê uma cadeia de caracteres não brancos pula os eventuais caracteres brancos antes da cadeia exemplo: char cidade[81];... scanf("%s", cidade);... &cidade não é usado pois a cadeia é um vetor o código acima funciona apenas para capturar nomes simples se o usuário digitar Rio de Janeiro, apenas Rio será capturada, pois %s lê somente uma seqüência de caracteres não brancos

Leitura de Caracteres e Strings com scanf scanf com o especificador de formato %[...] %[...] lista entre os colchetes todos os caracteres aceitos na leitura %[^...] lista entre os colchetes todos os caracteres não aceitos na leitura exemplos: %[aeiou] lê seqüências de vogais leitura prossegue até encontrar um caractere que não seja uma vogal %[^aeiou] lê seqüências de caracteres que não são vogais leitura prossegue até encontrar um caractere que seja uma vogal

Exemplo: Leitura de Caracteres e Strings com scanf lê uma seqüência de caracteres até que seja encontrado o caractere de mudança de linha ('\n') captura linha fornecida pelo usuário até que ele tecle Enter inclusão do espaço no formato garante que eventuais caracteres brancos que precedam a cadeia de caracteres sejam descartados char cidade[81];... scanf(" %[^\n]", cidade);... também pode ser usado " %[^\n]s OBS: se, na leitura de um segundo string, você não usar o branco antes do %, isto fará com que o scanf capture os caracteres brancos deixados na leitura anterior e coloque um string inesperado na variável scanf(" %[^\n]",cidade1); scanf("%[^\n]",cidade2); use ou scanf(" %[^\n]",cidade1); scanf(" %[^\n]",cidade2); scanf("%[^\n]",cidade1); getchar(); scanf("%[^\n]",cidade2);