Baixe o app para aproveitar ainda mais
Prévia do material em texto
A26: Arquivos de texto (2) Algoritmos e Programação Julio Toss jtoss@inf.ufrgs.br INF01202 – Algoritmos e Programação, 2018/01, Turmas G, H, K e L *baseado no material da prof. Mariana e do prof. Marcelo Walter Atenção: O material aqui contido não substitui a leitura do livro texto e é incompleto sem a apresentação do professor em aula. 2 Aula passada: Arquivos de texto Organização interna Modos de abertura 3 Manipulação Aula passada: Arquivos de texto Escrita e Leitura: 4 Linha a linha Caractere a caractere Faça um programa para substituir um determinado caractere em um arquivo texto existente por outro (ambos obtidos por leitura via teclado). As alterações devem ser gravadas no mesmo arquivo! Aula passada: exemplo Se as coisas sao inatingiveis... ora! Nao e' motivo para nao quere-las... Que tristes os caminhos se nao fora A magica presenca das estrelas! Mario Quintana 5 Faça um programa para substituir um determinado caractere em um arquivo texto existente por outro (ambos obtidos por leitura via teclado). As alterações devem ser gravadas no mesmo arquivo! Aula passada: exemplo Se @s cois@s s@o in@tingiveis... or@! N@o e' motivo p@r@ n@o quere-l@s... Que tristes os c@minhos se n@o for@ A m@gic@ presenc@ d@s estrel@s! M@rio Quint@n@ $ ./aula24-exercicio4 Caractere a procurar: a Substituir por: @ Numero de caracteres alterados: 21 6 #include<stdio.h> int main() { FILE *arq; char antigo, novo, lido; int numAlterados = 0; if ((arq = fopen("texto_original.txt", "r+")) == NULL) printf("Erro ao abrir \n"); else { printf("\nCaractere a procurar: "); scanf(" %c", &antigo); printf("\nSubstituir por: "); scanf(" %c", &novo); while (!feof(arq)) { lido = getc(arq); if(lido == antigo) { numAlterados++; fseek(arq, -1, SEEK_CUR); // volta a posição putc(novo, arq); // substitui fflush(arq); // grava mudanças no arquivo } } fclose(arq); printf("\nNumero de caracteres alterados: %d\n", numAlterados); } return 0; } 7 Código: Arquivos de Texto (2) 8 Arquivos de texto manipulam caracteres e strings. Hoje veremos funções auxiliares para manipulação de strings que podem facilitar a escrita e leitura de dados de arquivos de texto. Estas funções permitem maior flexibilidade na conversão de tipos de string para inteiro e real, por exemplo. Arquivos de texto: continuação 9 Função atoi (lê-se ascii to integer): converte o conteúdo de uma string para inteiro e retorna este valor. Sintaxe: int atoi(char str[]); Exemplo: Arquivos de texto: Funções auxiliares para strings 10 Função atof (lê-se ascii to float): converte o conteúdo de uma string para float e retorna este valor. Sintaxe: float atof(char str[]); Exemplo: Arquivos de texto: Funções auxiliares para strings 11 Processando arquivos de texto com delimitadores Em alguns casos, a informação está armazenada no arquivo texto em substrings (em Inglês tokens) separados por algum símbolo especial (o delimitador). Exemplo: veiculos.txt, onde os tokens estão separados por vírgula Modelo,chassi,peso,altura,comprimento,largura 12 Como ler este arquivo corretamente? Análise léxica: a informação contida em arquivos de texto pode ser recuperada de forma mais fácil se estruturada em trechos separados de forma clara. Token: cada trecho de texto com algum significado Delimitador: símbolos sem significado que indicam o final de um trecho e início do próximo (são caracteres que não serão usados no token, como %, #, /, etc.) Processando arquivos de texto com delimitadores Exemplo: veiculos.txt, onde os tokens estão separados por vírgula Modelo,chassi,peso,altura,comprimento,largura 13 As informações armazenadas em um arquivo texto (portanto em representação caractere), separados entre si por delimitadores (tipicamente caracteres diferentes do espaço, como vírgula, # ou /), podem ser extraídas e convertidas, se forem números, para a representação binária de inteiros ou reais. Veremos como extrair elementos de linhas de um arquivo texto, organizado em tokens separados por delimitador (como os exemplos abaixo) Processando arquivos de texto com delimitadores 14 Extração de elementos de linhas do arquivo texto Análise léxica: passo-a-passo 1. Ler toda a linha do arquivo como uma string (função fgets). 2. Extrair os tokens da string lida (função strtok). 3. Converter cada token ao tipo de dado correto (funções atoi e atof). 15 Extração de elementos de linhas do arquivo texto Análise léxica: passo-a-passo 1. Ler toda a linha do arquivo como uma string (função fgets). 2. Extrair os tokens da string lida (função strtok). 3. Converter cada token ao tipo de dado correto (funções atoi e atof). 16 Extração de elementos de linhas do arquivo texto Função fgets (revisando) 17 Extração de elementos de linhas do arquivo texto Análise léxica: passo-a-passo 1. Ler toda a linha do arquivo como uma string (função fgets). 2. Extrair os tokens da string lida (função strtok). 3. Converter cada token ao tipo de dado correto (funções atoi e atof). 18 Extração de elementos de linhas do arquivo texto Função strtok: extrai substrings (tokens) sucessivos de uma string, desde que separados por um delimitador definido como tal. - Retorna um ponteiro para o próximo token ou NULL quando não há mais tokens - Podemos especificar um ou mais símbolos separadores 19 Função strtok: exemplo 1 #include <stdio.h> #include <string.h> // strtok #define MAXCHAR 256 int main() { char linha[MAXCHAR] = {"parte1#outra parte#ultima parte"}; printf("Token 1 - %s", strtok(linha,"#")); printf("Token 2 - %s", strtok(NULL,"#")); printf("Token 3 - %s", strtok(NULL,"#")); return 0; } Extração de elementos de linhas do arquivo texto 20 ./Aula25-1 Token 1 - parte 1Token 2 - outra parteToken 3 - ultima parte Função strtok: exemplo 1 #include <stdio.h> #include <string.h> // strtok #define MAXCHAR 256 int main() { char linha[MAXCHAR] = {"parte1\n#outra parte\n#ultima parte\n"}; printf("Token 1 - %s", strtok(linha,"#")); printf("Token 2 - %s", strtok(NULL,"#")); printf("Token 3 - %s", strtok(NULL,"#")); return 0; } Extração de elementos de linhas do arquivo texto 21 ./Aula25-1 Token 1 - parte 1 Token 2 - outra parte Token 3 - ultima parte Se tiver '\n', é lido como parte da substring! Função strtok: exemplo 2, listando as palavras em uma frase, com mais de um símbolo separador #include <stdio.h> #include <string.h> // strtok int main (){ char frase[] = "- Este e' um exemplo de frase, ou seja, string."; char *palavra; printf ("Separando a frase \"%s\" em palavras:\n",frase); palavra = strtok( frase, " ,.-"); while (palavra != NULL){ printf("%s\n", palavra); palavra = strtok( NULL, " ,.-"); } return 0; } Extração de elementos de linhas do arquivo texto 22 Função strtok: exemplo 2, listando as palavras em uma frase, com mais de um símbolo separador #include <stdio.h> #include <string.h> // strtok int main (){ char frase[] = "- Este e' um exemplo de frase, ou seja, string."; char *palavra; printf ("Separando a frase \"%s\" em palavras:\n",frase); palavra = strtok( frase, " ,.-"); while (palavra != NULL){ printf("%s\n", palavra); palavra = strtok( NULL, " ,.-"); } return 0; } Extração de elementos de linhas do arquivo texto 4 separadores neste exemplo: - espaço - vírgula - ponto - hífen 23 Função strtok: exemplo 2, listando as palavras em uma frase, com mais de um símbolo separador #include<stdio.h> #include <string.h> // strtok int main (){ char frase[] = "- Este e' um exemplo de frase, ou seja, string."; char *palavra; printf ("Separando a frase \"%s\" em palavras:\n",frase); palavra = strtok( frase, " ,.-"); while (palavra != NULL){ printf("%s\n", palavra); palavra = strtok( NULL, " ,.-"); } return 0; } Extração de elementos de linhas do arquivo texto 4 separadores neste exemplo: - espaço - vírgula - ponto - hífen 24 root@Rodro-Linux:~# ./a.out Separando a frase "- Este e' um exemplo de frase, ou seja, string." em palavras: Este e' um exemplo de frase ou seja string Função strtok: exemplo 2.2, listando as palavras em uma frase, com mais de um símbolo separador #include <stdio.h> #include <string.h> // strtok int main (){ char frase[] = "- Este e' um exemplo de frase, ou seja, string."; char *palavra; printf ("Separando a frase \"%s\" em palavras:\n",frase); palavra = strtok( frase, ",.-"); while (palavra != NULL){ printf("%s\n", palavra); palavra = strtok( NULL, ",.-"); } return 0; } Extração de elementos de linhas do arquivo texto 3 separadores neste exemplo: - vírgula - ponto - hífen retirando o espaço dos delimitadores 25 Função strtok: exemplo 2.2, listando as palavras em uma frase, com mais de um símbolo separador #include <stdio.h> #include <string.h> // strtok int main (){ char frase[] = "- Este e' um exemplo de frase, ou seja, string."; char *palavra; printf ("Separando a frase \"%s\" em palavras:\n",frase); palavra = strtok( frase, ",.-"); while (palavra != NULL){ printf("%s\n", palavra); palavra = strtok( NULL, ",.-"); } return 0; } Extração de elementos de linhas do arquivo texto 3 separadores neste exemplo: - vírgula - ponto - hífen retirando o espaço dos delimitadores 26 root@Rodro-Linux:~# ./a.out Separando a frase "- Este e' um exemplo de frase, ou seja, string." em palavras: Este e' um exemplo de frase ou seja string Função strtok: exemplo 2.3, listando as palavras em uma frase, com mais de um símbolo separador #include <stdio.h> #include <string.h> // strtok int main (){ char frase[] = "- Este e' um exemplo de frase.\n- ou seja, e' uma string."; char *palavra; printf ("Separando a frase \"%s\" em palavras:\n",frase); palavra = strtok( frase, " ,.-"); while (palavra != NULL){ printf("%s\n", palavra); palavra = strtok( NULL, " ,.-"); } return 0; } Extração de elementos de linhas do arquivo texto 4 separadores neste exemplo: - espaço - vírgula - ponto - hífen 27 adicionando nova linha Função strtok: exemplo 2.3, listando as palavras em uma frase, com mais de um símbolo separador #include <stdio.h> #include <string.h> // strtok int main (){ char frase[] = "- Este e' um exemplo de frase.\n- ou seja, e' uma string."; char *palavra; printf ("Separando a frase \"%s\" em palavras:\n",frase); palavra = strtok( frase, " ,.-"); while (palavra != NULL){ printf("%s\n", palavra); palavra = strtok( NULL, " ,.-"); } return 0; } Extração de elementos de linhas do arquivo texto 4 separadores neste exemplo: - espaço - vírgula - ponto - hífen 28 adicionando nova linharoot@Rodro-Linux:~# ./a.out Separando a frase "- Este e' um exemplo de frase. - ou seja, e' uma string." em palavras: Este e' um exemplo de frase ou seja e' uma string na linha printf("%s\n", palavra);, um \n em palavra e outro na formatação do printf Função strtok: exemplo 2.4, listando as palavras em uma frase, com mais de um símbolo separador #include <stdio.h> #include <string.h> // strtok int main (){ char frase[] = "- Este e' um exemplo de frase.\n- ou seja, e' uma string."; char *palavra; printf ("Separando a frase \"%s\" em palavras:\n",frase); palavra = strtok( frase, " ,.-\n"); while (palavra != NULL){ printf("%s\n", palavra); palavra = strtok( NULL, " ,.-\n"); } return 0; } Extração de elementos de linhas do arquivo texto 5 separadores neste exemplo: - espaço - vírgula - ponto - hífen - nova linha 29 adicionando delimitador nova linha Função strtok: exemplo 2.4, listando as palavras em uma frase, com mais de um símbolo separador #include <stdio.h> #include <string.h> // strtok int main (){ char frase[] = "- Este e' um exemplo de frase.\n- ou seja, e' uma string."; char *palavra; printf ("Separando a frase \"%s\" em palavras:\n",frase); palavra = strtok( frase, " ,.-\n"); while (palavra != NULL){ printf("%s\n", palavra); palavra = strtok( NULL, " ,.-\n"); } return 0; } Extração de elementos de linhas do arquivo texto 5 separadores neste exemplo: - espaço - vírgula - ponto - hífen - nova linha 30 adicionando delimitador nova linha root@Rodro-Linux:~# ./a.out Separando a frase "- Este e' um exemplo de frase. - ou seja, e' uma string." em palavras: Este e' um exemplo de frase ou seja e' uma string Exercício: desenvolver um programa em C contendo uma função void ConvertePontuacao(FILE *arqPont, int vetPont[]) com as seguintes funcionalidades. - recebe um ponteiro para arquivo texto composto de sequências de dígitos numéricos inteiros positivos sucedidos por asterisco - lê os dados do arquivo e converte cada sequência em um número inteiro - armazena cada número em um vetor recebido como parâmetro - insere -1 ao final do vetor, sinalizando o final dos pontos *considere que há, no máximo 100 sequências de dígitos no arquivo! Extração de elementos de linhas do arquivo texto 31 #include <stdio.h> #include <string.h> #define MAXNUMEL 101 // 100 elementos + o indicador de fim (-1) // declaração da função ConvertePontuação //void ConvertePontuacao(FILE *arqPont, int vetPont[]) {...} int main() { FILE *pArq; int pontos[MAXNUMEL], i=0; if ( !(pArq=fopen("pontos.txt", "r")) ) printf("Erro ao abrir arquivo!\n"); else { ConvertePontuacao(pArq, pontos); fclose(pArq); printf("\nVetor resultante da conversao:\n"); while (pontos[i] != -1){ printf(" %d ", pontos[i]); i++; } printf("\n"); } // if-else return 0; } Extração de elementos de linhas do arquivo texto 32 void ConvertePontuacao(FILE *arqPont, int vetPont[]) { char pontEmTexto[10*100+100+1]; // máximo: 100 elementos de 10 dígitos (bilhão) + 100 asteríscos char *numero; int indVet=0; if ( fgets(pontEmTexto, sizeof(pontEmTexto), arqPont) == NULL ) printf("\nErro: nao leu nada!\n"); else { numero = strtok(pontEmTexto,"*"); while (numero != NULL) { vetPont[indVet] = atoi(numero); indVet++; numero = strtok(NULL,"*"); } vetPont[indVet] = -1; // sinalizador de fim de valores convertidos } // if-else } Extração de elementos de linhas do arquivo texto 33 i) ler os dados de 20 alunos; ii) calcular as médias finais de cada aluno e armazenar em um vetor; iii) calcular a média da turma; iv) exibir na tela, na forma de uma tabela, o nome e código de cada aluno, seguidos das suas notas parciais e da nota final. Estenda este exercício para o uso de arquivos texto. - Leia os dados dos alunos de um arquivo de texto (neste caso, sem validação da nota) - Salve a tabela em outro arquivo de texto. Tarefa - Exercício de revisão (aula 24) 34
Compartilhar