Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original
DCC 119 Algoritmos 2 Uma cadeia de caracteres é uma sequência de caracteres justapostos e são fundamentais no desenvolvimento de programas computacionais. Exemplos de cadeias de caracteres (representadas internamente num programa): Mensagem de e-mail; Texto de um programa; Nome e endereço em cadastro de clientes, alunos, etc... Sequencia genética. Um gene (ou o DNA de algum organismo) é composto de sequencias dos caracteres A, T, G e C (nucleotídeos) Cadeias de caracteres 3 Uma variável usada para armazenar um caractere é representada da seguinte maneira: caracter letra; //a variável letra do tipo caracter letra a ; // atribuída a letra a a variável letra Se em uma variável do tipo caracter podemos armazenar somente um caractere, então para armazenar vários caracteres (ex: jose , carro ) é necessário utilizar as cadeias de caracteres, representadas por vetores do tipo caracter. Caracteres - Revisão 4 Observe a declaração abaixo: caracter cidade[12] ; A variável cidade é um vetor de caracteres (cadeia de caracteres) A variável cidade pode armazenar qualquer cadeia de até 12 caracteres Caracteres - Revisão J u i z d e F o r a 0 1 2 3 4 5 6 7 8 9 10 11 cidade 5 Cadeias de Caracteres (Strings) Sintaxe para declaração de cadeia de caracteres caracter identificador[qtde caracteres]; Exemplo: caracter nome[30]; caracter profissao[20]; 6 Cadeias de Caracteres (Strings) Manipulação de cadeias de caracteres Vamos atribuir a variável nome, criada anteriormente, o nome Jose. nome Jose ; Observe a presença das aspas duplas na palavra Jose. Podemos ainda, obter um caracter qualquer da cadeia de caracteres da seguinte maneira: caracter letra nome[1]; // letra receberá a letra da posição 1 da cadeia de caracteres, ou seja, o . 7 Cadeia de caracteres (Strings) Exemplo: principal { caracter s[20]; imprima ( Digite uma string: ) ; leia (s); imprima ( String digitada: ,s); } 8 Caracteres em C Os caracteres em C são representados internamente por códigos numéricos (ASCII); }|{zyx120 wvutsrqpon110 mlkjihgfed100 cba`_^]\[Z90 YXWVUTSRQP80 ONMLKJIHGF70 EDCBA@?>=<60 ;:9876543250 10/.-,+*)(40 '&%$#"!sp30 9876543210 sp: espaço em branco Alguns caracteres visíveis (podem ser impressos) 9 Caracteres em C A diferença entre caracteres e inteiros está apenas na maneira como são tratados, por exemplo, o código char c = 97; printf("int : %d char : %c\n", c, c); Imprimirá int : 97 char : a O conteúdo da variável c é impressa em dois formatos distintos: %d (int) e %c (char). 10 Caracteres em C Por questão de portabilidade, não se deve usar diretamente, no programa, o código de caracteres; Ao invés, usa-se uma constante caractere: caractere entre apóstrofe. Reescrevendo o fragmento de código anterior: char c = 'a'; printf("int : %d char: %c\n", c, c); Imprimirá int : 97 char : a Pode-se trocar char c por int c: o resultado será o mesmo. 11 Caracteres em C Entrada/Saída de caracteres em C: ch = getchar(); armazena um caractere digitado em ch até que ENTER seja pressionado; putchar(ch); Imprime o caractere ch na tela do computador; Exemplo: int main() { char ch; ch = getchar(); putchar(ch); return 0; } 12 Cadeias de caracteres são similares em C e em pseudolinguagem: Cadeias de caracteres e Strings char graus[5] = { A', B', C', A , D'} ; char bin[8] = { 0', 1', 0', 1', 1', 1', 0', 1'} ; 13 Strings são tipos especiais de cadeias de caracter em C e são terminadas, obrigatoriamente, pelo caractere nulo: \0 (\zero). Portanto, deve-se reservar uma posição para este caractere de fim de cadeia. Em pseudolinguagem, cadeias de caracteres e strings são semelhantes. Desta forma, para fins de implementação, trataremos o assunto apenas em C. Strings 14 Exemplos de strings em C: Outras formas de inicializarmos strings em C: Strings char cidade[4] = { 'R', 'i', 'o', \0'}; char disc[40] = {'A','l','g', 'o', 'r', 'i', 't', 'm', 'o', '\0'}; char cidade[4] = "Rio"; char disc[40] = "Algoritmo"; 15 Para ilustrar a declaração e a inicialização de strings, consideremos as seguintes declarações: Strings char s1[] = "" ; //2 aspas sem espaços entre elas char s2[] = "Rio de Janeiro"; char s3[81]; char s4[81] = "Rio"; s1 armazena uma string vazia. Tem um único elemento: \0 ; s2 representa um vetor com 15 elementos (caracteres); s3 representa uma cadeia de caracteres com até 80 caracteres e não é inicializada; s4 também é dimensionada para conter até 80 caracteres e é inicializada com a cadeia Rio . 16 Leitura de strings (scanf). Strings int main() { char s[20]; printf("Digite uma string: "); scanf("%s",s); //sem & antes de s printf("String digitada: %s",s); return 0; } Neste caso, a leitura será feita até encontrar um caractere branco: espaço (' '), tabulação ( \t') ou nova linha ( \n'). Assim, se digitarmos Rio de Janeiro , s conterá apenas Rio ; Não é necessário o & antes da variável s em scanf. 17 Leitura/Impressão de strings (gets/puts). Strings int main() { char s[20]; printf("Digite uma string: "); gets(s); printf("String digitada: "); puts(s); return 0; } Neste caso, se digitarmos Rio de Janeiro , s conterá Rio de Janeiro ; gets(s): lê a string s a partir do teclado; puts(s): imprime uma string na tela seguida de nova linha. 18 Exemplo: o programa a seguir imprime uma cadeia de caracteres, caractere por caractere: Strings int main() { char s[30]; int i; printf("Digite uma string: "); gets(s); //imprime cada caractere da cadeia lida for(i=0; s[i]!='\0'; i++) printf("%c",s[i]); return 0; } O for acima equivale a printf("%s",s); 19 Exemplo: o programa a seguir calcula e imprime o comprimento (numero de caracteres) de uma cadeia: Strings int main() { char s[30]; int i, n = 0; printf("Digite uma string: "); gets(s); for(i=0; s[i]!='\0'; i++) n++; printf("\nO tamanho de \"%s\" eh: %d",s,n); return 0; } 20 Exemplo: o programa a seguir faz uma copia de uma cadeia, fornecida pelo usuário, para outra: Strings int main() { char dest[50], //string destino orig[50]; //string origem int i; printf("Digite uma string: "); gets(orig); //copia cada caractere de orig para dest for(i=0; orig[i]!='\0'; i++) dest[i] = orig[i]; //coloca o caractere nulo para marcar o fim da string dest[i] = '\0'; puts(dest); return 0; } 21 Funções para manipulação de Strings Existem várias funções em C para manipulação de strings. Essas funções estão declaradas no arquivo string.h. Entre elas pode-se destacar: strcpy(char destino[ ], char origem[ ]) copia a string origem na string destino strlen(char str[ ]) retorna o tamanho da string str strcat(char destino[ ], char origem[ ]) Faz concatenação (junção) da string origem com a string destino. O resultado é armazenado na string destino 22 Exercício resolvido 1 Criar uma função que receba como parâmetro uma cadeia de caracteres (cadeia), seu tamanho (tam) e um segundo caractere (procurado). A função deverá retornar a quantidade que o caractere procurado foi encontrado na cadeia. Solução: Precisamos varrer a cadeia de caracteres (estrutura de repetição) e contar quantos são iguais ao caractere procurado, caractere a caractere. 23 Solução proposta em pseudolinguagem inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } 24 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 25 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Função é chamada O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 26 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Variáveis: i = 0 encontrados = 0 Variáveis são criadas e inicializadas O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 27 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Estrutura de repetição onde será a feita a busca é iniciada Variáveis: i = 0 encontrados = 0 O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 28 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Testa primeiro caractere da cadeira com o procurado Variáveis: i = 0 encontrados = 0 O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 29 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Como teste é válido, incrementa contador Variáveis: i = 0 encontrados = 1 O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 30 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Vai para o próximo indice da cadeia Variáveis: i = 1 encontrados = 1 O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 31 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Continua na estrutura de repetição Variáveis: i = 1 encontrados = 1 O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 32 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Testa segundo caractere e falha! Variáveis: i = 1 encontrados = 1 O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 33 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Variáveis: i = 2 encontrados = 1 Vai para o próximo indice da cadeia O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 34 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Variáveis: i = 2 encontrados = 1 Continua na estrutura de repetição O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 35 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Variáveis: i = 2 encontrados = 1 Testa terceiro caractere e falha! O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 36 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Variáveis: i = 3 encontrados = 1 Vai para o próximo índice da cadeia O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 37 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Variáveis: i = 3 encontrados = 1 Continua na estrutura de repetição O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 38 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Variáveis: i = 3 encontrados = 1 Testa quarto caractere... O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 39 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Como teste é válido, incrementa contador Variáveis: i = 3 encontrados = 2 O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 40 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Vai para o próximo indice da cadeia Variáveis: i = 4 encontrados = 2 O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 41 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Variáveis: i = 4 encontrados = 2 Continua na estrutura de repetição O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 42 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Variáveis: i = 4 encontrados = 2 Testa terceiro caractere e falha! O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 43 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Variáveis: i = 5 encontrados = 2 Vai para o próximo índice da cadeia O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 44 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Variáveis: i = 5 encontrados = 2 Falha o teste da estrutura de repetição O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 45 inteiro conta( caracter cadeia[], inteiro tam, caracter procurado ) { inteiro encontrados, i; i 0; encontrados 0; enquanto ( i < tam ) faça { se (cadeia[i] = procurado) { encontrados encontrados + 1; } i i + 1; } retorne encontrados; } etset t Variáveis: i = 5 encontrados = 2 Retorna o número de caracteres encontrados: 2 O teste será realizado supondo que: cadeia = teste tam = 5 procurado = t 46 Exercício resolvido 2: Busca em Strings em C Criar uma função para verificar se a string s2 está contida na string s1. A função deverá retornar 1 se encontrar a string ou 0, caso contrário. Ex.: Se s1 fosse Ana Maria Silva e s2 fosse Maria , a função retornaria 1, pois s2 está contido em s1. 47 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } O teste será realizado supondo que: s1 = Este é um teste s2 = um 48 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } etsetmuéetsE mu Função é chamada passando- se s1 e s2 como parâmetro 49 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } etsetmuéetsE mu Variáveis: i = j = aux = tam1 = 15 tam2 = 2 Variáveis são criadas e inicializadas. tam1 recebe o tamanho de s1 e tam2 recebe o tamanho de s2. 50 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } etsetmuéetsE mu Variáveis: i = 0 j = aux = tam1 = 15 tam2 = 2 A idéia central é varrer s1 comparando com s2, caracter a caracter. 51 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } etsetmuéetsE mu Variáveis: i = 0 j = 0 aux = 0 tam1 = 15 tam2 = 2 Para fazer a comparação, uma variável auxiliar (aux) será utilizada. 52 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } etsetmuéetsE mu Variáveis: i = 0 j = 0 aux = 0 tam1 = 15 tam2 = 2 Como caracteres não são iguais, executa o break! 53 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } etsetmuéetsE mu Variáveis: i = 0 j = 0 aux = 0 tam1 = 15 tam2 = 2 Falha nessa condição e continua no loop externo 54 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } etsetmuéetsE mu Variáveis: i = 1 j = 0 aux = 0 tam1 = 15 tam2 = 2 Vai para a próxima iteração do loop externo! 55 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } etsetmuéetsE mu Variáveis: i = 1 j = 0 aux = 1 tam1 = 15 tam2 = 2 Busca agora começa do segundo caracter de s1 em relação ao primeiro de s2 e falha. 56 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } Falha nessa condição e continua no loop externo Variáveis: i = 1 j = 0 aux = 1 tam1 = 15 tam2 = 2 etsetmuéetsE mu 57 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } etsetmuéetsE mu Variáveis: i = 2 j = 0 aux = 2 tam1 = 15 tam2 = 2 Testando os próximos elementos em busca de um válido 58 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } etsetmuéetsE mu Variáveis: i = 3 j = 0 aux = 3 tam1 = 15 tam2 = 2 Testando os próximos elementos em busca de um válido 59 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } etsetmué_etsE mu Variáveis: i = 4 j = 0 aux = 4 tam1 = 15 tam2 = 2 Testando os próximos elementos em busca de um válido 60 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } etsetmuéetsE mu Variáveis: i = 5 j = 0 aux = 5 tam1 = 15 tam2 = 2 Testando os próximos elementos em busca de um válido 61 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } etsetmu_éetsE mu Variáveis: i = 6 j = 0 aux = 6 tam1 = 15 tam2 = 2 Testando os próximos elementos em busca de um válido 62 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } etsetmuéetsE mu Variáveis: i = 7 j = 0 aux = 7 tam1 = 15 tam2 = 2 Testando os próximos elementos em busca de um válido 63 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } etsetmuéetsE mu Variáveis: i = 7 j = 0 aux = 8 tam1 = 15 tam2 = 2 Teste falha e incrementa variável aux. 64 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } etsetmuéetsE mu Variáveis: i = 7 j = 1 aux = 8 tam1 = 15 tam2 = 2 Passa para a próxima iteração do loop interno 65 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } etsetmuéetsE mu Variáveis: i = 7 j = 1 aux = 9 tam1 = 15 tam2 = 2 Teste falha novamente e aux é incrementado 66 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } etsetmuéetsE mu Variáveis: i = 7 j = 2 aux = 9 tam1 = 15 tam2 = 2 j é incrementado e sai do laço pois a condição j < tam2 falha 67 int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 = strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } etsetmuéetsE mu Variáveis: i = 7 j = 2 aux = 9 tam1 = 15 tam2 = 2 Como j = tam2, sai da função retornando 1. 68 Programa Completo #include <stdio.h> #include <string.h> int buscaString(char s1[], char s2[]) { int i,j,aux, tam1, tam2; tam1 = strlen(s1); tam2 =strlen(s2); for(i=0;i<tam1;i++) { aux=i; for(j=0;j<tam2 && aux<tam1;j++) { if (s2[j] != s1[aux]) break; aux++; } if (j == tam2) return 1; } return 0; } int main() { char s1[100], s2[100]; gets(s1); gets(s2); int resultado = buscaString(s1, s2); if(resultado) printf("Encontrou a string"); else printf("Não encontrou a string"); return 0; } 69 Exercícios 1)Fazer um programa para contar o número de espaços em brancos de uma string. 2) Refaça o programa anterior criando uma função que receberá como parâmetro a string e retornará o número de espaços em branco que a string contem. 3) Fazer um programa para contar o número de vogais numa cadeia de caractere. 4) Refaça o programa anterior criando uma função que receberá como parâmetro a string e retornará o número de vogais que a string contem. 70 Exercícios 5) Escrever um programa para ler uma string (com mais de uma palavra) e faça com que a primeira letra de cada palavra fique em maiúscula. Para isso, basta subtrair 32 do elemento que deseja alterar para maiúsculo. chrNome[0] = chrNome[0] 32; Exemplo: Entrada: lab. de linguagem de programacao Saída: Lab. De Linguagem De Programacao 6)Escreva uma função que receba uma string, conte quantos caracteres desta string são iguais a 'a' e substitua os que forem iguais a 'a' por 'b'. A função deverá retornar o número de caracteres modificados. 71 Cadeias de caracteres (strings) 7) Crie um procedimento que receba uma frase e a exiba na tela de forma soletrada, ou seja, cada letra deve ser exibida na tela separada por hífen. 8) Crie um procedimento que receba uma string de no máximo 50 caracteres e inverta a ordem da string digitada; Exemplo: Entrada: Teste Saída: etseT 9)Fazer um programa para determinar e imprimir uma string que será a concatenação de duas outras strings lidas. DCC120 73 Caracteres em C Os caracteres em C são representados internamente por códigos numéricos (ASCII); }|{zyx120 wvutsrqpon110 mlkjihgfed100 cba`_^]\[Z90 YXWVUTSRQP80 ONMLKJIHGF70 EDCBA@?>=<60 ;:9876543250 10/.-,+*)(40 '&%$#"!sp30 9876543210 sp: espaço em branco Alguns caracteres visíveis (podem ser impressos) 74 Caracteres em C A diferença entre caracteres e inteiros está apenas na maneira como são tratados, por exemplo, o código char c = 97; printf("int : %d char : %c\n", c, c); Imprimirá int : 97 char : a O conteúdo da variável c é impressa em dois formatos distintos: %d (int) e %c (char). 75 Caracteres em C Por questão de portabilidade, não se deve usar diretamente, no programa, o código de caracteres; Ao invés, usa-se uma constante caractere: caractere entre apóstrofe. Reescrevendo o fragmento de código anterior: char c = 'a'; printf("int : %d char: %c\n", c, c); Imprimirá int : 97 char : a Pode-se trocar char c por int c: o resultado será o mesmo. 76 Caracteres em C Entrada/Saída de caracteres em C: ch = getchar(); armazena um caractere digitado em ch até que ENTER seja pressionado; putchar(ch); Imprime o caractere ch na tela do computador; Exemplo: int main() { char ch; ch = getchar(); putchar(ch); return 0; } 77 Caracteres em C Exemplo: programa para verificar se um dado caractere c é um dígito (aproveita o fato de os dígitos estarem em sequência na tabela ASCII): int main() { char c; printf("Digite uma letra ou numero: "); c = getchar(); if((c >= '0') && (c<='9')) printf("Eh um digito"); else printf("Nao eh um digito"); return 0; } 78 Caracteres em C Exemplo: programa para converter uma letra (caractere) minúscula para maiúsculo (aproveita o fato de os caracteres estarem em sequência na tabela ASCII): int main() { char c; printf("Digite uma letra: "); c = getchar(); //verifica se é letra minúscula if(c >= 'a' && c<='z') //imprime c em letra maiuscula putchar(c - 'a' + 'A'); return 0; } 79 Cadeias de caracteres em C são representadas por vetores do tipo char. Cadeias de caracteres e Strings char graus[5] = { A', B', C', A , D'} ; char bin[8] = { 0', 1', 0', 1', 1', 1', 0', 1'} ; 80 Strings são cadeias de caracter terminadas, obrigatoriamente, pelo caractere nulo: \0 (\zero). Portanto, deve-se reservar uma posição para este caractere de fim de cadeia. Exemplos: Equivale: Strings char cidade[4] = { 'R', 'i', 'o', \0'}; char disc[40] = {'A','l','g', 'o', 'r', 'i', 't', 'm', 'o', '\0'}; char cidade[4] = "Rio"; char disc[40] = "Algoritmo"; 81 Para ilustrar a declaração e a inicialização de strings, consideremos as seguintes declarações: Strings char s1[] = "" ; //2 aspas sem espaços entre elas char s2[] = "Rio de Janeiro"; char s3[81]; char s4[81] = "Rio"; s1 armazena uma string vazia. Tem um único elemento: \0 ; s2 representa um vetor com 15 elementos (caracteres); s3 representa uma cadeia de caracteres com até 80 caracteres e não é inicializada; s4 também é dimensionada para conter até 80 caracteres e é inicializada com a cadeia Rio . 82 Leitura de strings (scanf). Strings int main() { char s[20]; printf("Digite uma string: "); scanf("%s",s); //sem & antes de s printf("String digitada: %s",s); return 0; } Neste caso, a leitura será feita até encontrar um caractere branco: espaço (' '), tabulação ( \t') ou nova linha ( \n'). Assim, se digitarmos Rio de Janeiro , s conterá apenas Rio ; Não é necessário o & antes da variável s em scanf. 83 Leitura/Impressão de strings (gets/puts). Strings int main() { char s[20]; printf("Digite uma string: "); gets(s); printf("String digitada: "); puts(s); return 0; } Neste caso, se digitarmos Rio de Janeiro , s conterá Rio de Janeiro ; gets(s): lê a string s a partir do teclado; puts(s): imprime uma string na tela seguida de nova linha. 84 Exemplo: o programa a seguir imprime uma cadeia de caracteres, caractere por caractere: Strings int main() { char s[30]; int i; printf("Digite uma string: "); gets(s); //imprime cada caractere da cadeia lida for(i=0; s[i]!='\0'; i++) printf("%c",s[i]); return 0; } O for acima equivale a printf("%s",s); 85 Exemplo: o programa a seguir calcula e imprime o comprimento (numero de caracteres) de uma cadeia: Strings int main() { char s[30]; int i, n = 0; printf("Digite uma string: "); gets(s); for(i=0; s[i]!='\0'; i++) n++; printf("\nO tamanho de \"%s\" eh: %d",s,n); return 0; } 86 Exemplo: o programa a seguir faz uma copia de uma cadeia, fornecida pelo usuário, para outra: Strings int main() { char dest[50], //string destino orig[50]; //string origem int i; printf("Digite uma string: "); gets(orig); //copia cada caractere de orig para dest for(i=0; orig[i]!='\0'; i++) dest[i] = orig[i]; //coloca o caractere nulo para marcar o fim da string dest[i] = '\0'; puts(dest); return 0; } 87 Funções para manipulação de Strings Existem várias funções em C para manipulação de strings. Essas funções estão declaradas no arquivo string.h. Entre elas pode-se destacar: strcpy(char destino[ ], char origem[ ]) copia a string origem na string destino strlen(char str[ ]) retorna o tamanho da string str strcat(char destino[ ], char origem[ ]) Faz concatenação (junção) da string origem com a string destino. O resultado é armazenado na string destino 88 Exercícios 1)Fazer um procedimento para imprimir uma string recebida como parâmetro sem os espaços em branco. 2)Fazer um procedimento para receber uma string do usuário (máx. 50 caracteres) e imprimir uma estatística dos caracteres digitados. Isto é, imprimir o número de vogais, consoantes e outros caracteres. 3)Fazer um programa para ler uma string e transfira as consoantes para um vetor e as vogais para outro. Depois mostre cada um dos vetores. 89 Exercícios 4)Faça uma função que receba uma string do usuário (máx. 20 caracteres) e um caractere qualquer. A função deverá remover todas as ocorrências do caractere da string e retornar o número de remoções. 5)Escreva uma função que receba uma cadeia de caracteres de tamanho máximo 100, e retornar 1 se esta cadeia é uma palíndrome e zero caso contrário. Uma palavra é dita ser palíndrome se a seqüência de seus caracteres da esquerda para a direita é igual a seqüência de seus caracteres da direita para a esquerda. Ex.: arara, asa. 90 Exercícios 6)Um dos sistemas de encriptação mais antigos é atribuído a Júlio César: se uma letra a ser encriptada é a letra de número N do alfabeto, substitua-a com a letra (N+K), onde K é um número inteiro constante (César utilizava K = 3). Dessa forma, para K = 1 a mensagem Ataque ao amanhecer se torna bubrfabpabnboifdfs . Faça um programa que receba como entrada uma mensagem e um valor de K e retorne a mensagem criptografada pelo código de César. 91 DESAFIO!!! 7) Montar uma biblioteca com funções para manipular strings. IDEIA: Uma biblioteca é um conjunto de subrotinas e tipos de dados que você pode incluir no seu programa sem a necessidade de digitar novamente o código. Exemplo: #include <stdio.h> // biblioteca do sistema! Podemos criar nossas próprias bibliotecas! 92 Como fazer: 1) No seu Projeto, crie e inclua um novo arquivo chamado biblio.h , onde iremos colocar somente os protótipos das subrotinas da nossa biblioteca. 2) Crie e inclua no mesmo Projeto o arquivo biblio.c , onde iremos colocar a implementação das subrotinas prototipadas no arquivo biblio.h 3) No arquivo main.c do seu projeto, basta fazer referência à biblioteca criada (#include biblio.h ). Observe que você não utilizou os sinais de maior e menor para indicar a biblioteca, mas sim aspas. Isso indica que a biblioteca está no mesmo diretório do projeto. 93 Agora, construa sua biblioteca que forneça os principais recursos para a manipulação de strings. Sendo as funcionalidades propostas: Copia(): copia uma string para outra Compara(): compara duas strings Minusculo(): transforma os caracteres em minúsculo Maiusculo(): transforma os caracteres em maiúsculo Sentenca(): organiza a string como sentença Pessoa(): coloca os caracteres iniciais em maiúsculo Soma(): soma duas strings ProcuraTrecho(): procura uma string em outra ProcuraCaracter(): procura o ocorrência de caracteres na string