Caracteres, Cadeias (“Strings”) Registos em Ficheiros

Slides:



Advertisements
Apresentações semelhantes
Programação em Java Prof. Maurício Braga
Advertisements

Ludwig Krippahl, 2009 Programação para as Ciências Experimentais 2008/9 Teórica 5.
Ludwig Krippahl, 2007 Programação para as Ciências Experimentais 2006/7 Teórica 5.
Ludwig Krippahl, 2008 Programação para as Ciências Experimentais 2007/8 Teórica 3.
Ludwig Krippahl, 2008 Programação para as Ciências Experimentais 2007/8 Teórica 6.
Ludwig Krippahl, 2007 Programação para as Ciências Experimentais 2006/7 Teórica 2.
Ludwig Krippahl, 2009 Programação para as Ciências Experimentais 2008/9 Teórica 4.
Ludwig Krippahl, 2009 Programação para as Ciências Experimentais 2008/9 Teórica 6.
Introdução aos Computadores e à Programação DI-FCT-UNL-2005/2006 Introdução 1.1 Octave Cadeias e ficheiros.
Ludwig Krippahl, 2008 Programação para as Ciências Experimentais 2007/8 Teórica 2.
27 Abril de 2006Recursividade e Iteração1 Processamento de Texto Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2005/2006.
Introdução aos Computadores e Programação DI-FCT-UNL-2005/2006 Strings, operadores e funções 3.1 Octave Matrizes (cont.) e strings.
Integração Numérica – Áreas e Equações
Entradas, Saídas e Análise de Dados Regressão Linear
Introdução aos Computadores e Programação DI-FCT-UNL-2003/2004 Programação 5.1 Octave Programação.
Ludwig Krippahl, 2009 Programação para as Ciências Experimentais 2008/9 Teórica 2.
Ludwig Krippahl, 2007 Programação para as Ciências Experimentais 2006/7 Teórica 3.
Ludwig Krippahl, 2008 Programação para as Ciências Experimentais 2007/8 Teórica 4.
Vectores (e Listas) : Pesquisa e Ordenação
17 Novembro 2006Algoritmos de Ordenação e Pesquisa Aplicação a Listas de Registos 1 Jorge Cruz DI/FCT/UNL Introdução aos Computadores e à Programação 1º
Vectores e Matrizes Aplicações à Engenharia
Introdução aos Computadores e à Programação DI-FCT-UNL-2006/2007 Ficheiros 5.1 Octave Ficheiros.
1 Funções Trajectória de Projéctil DI/FCT/UNL 1º Semestre 2004/2005.
Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/ Maio 20091Registos em.
Recursividade e Iteração Factorial, Fibonacci e Maior Divisor Comum
Ciclos, Vectores e Gráficos Simulação da Queda de Corpos II
11 de Maio de 2006Listas e Ordenação1 Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2005/2006.
17 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.
Processamento de Texto Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/ Maio 20081Processamento de Texto.
Miguel Maurício Introdução aos Computadores e Programação DI-FCT-UNL-2004/2005 Programação 5.1 Octave Programação.
Introdução aos Computadores e à Programação DI-FCT-UNL-2006/2007 Strings 4.1 Octave Strings.
Entradas, Saídas e Análise de Dados Leitura e Escrita de Ficheiros
1 Funções, Expressões e Excepções Trajectórias Óptimas DI/FCT/UNL 1º Semestre 2004/2005.
1 Processamento de Registos Listas e Estruturas DI/FCT/UNL 1º Semestre 2004/2005.
10 Novembro 2006Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.
Introdução aos Computadores e à Programação
Pesquisa e Ordenação de Vectores
5 de Maio de 2005Registos em Ficheiros1 Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Maio 2005.
2 de Junho de 2005Conclusão1 Pedro Barahona DI/FCT/UNL Junho 2005.
Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2007/ Maio 20081Registos em.
11 Novembro 2005Processamento de Texto1 Jorge Cruz DI/FCT/UNL Programação para as Ciências Experimentais 1º Semestre 2005/2006.
Recursividade e Iteração (cont.) Processamento de Texto
1 Conclusão DI/FCT/UNL 1º Semestre 2004/ Ciclos de Simulação A técnica usada no exemplo da queda livre pode ser utilizada para trajectórias a duas.
Entradas, Saídas e Análise de Dados Regressão Linear
27 Abril 2007Processamento de Texto1 Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2006/2007.
Introdução aos Computadores e à Programação
Software Básico Silvio Fernandes Universidade Federal Rural do Semi-Árido Departamento de Ciências Exatas e Naturais Ciência da Computação Aula.
Software Básico Silvio Fernandes
Resolução.
Árvores.
EXPRESSÕES ARITMÉTICAS
EXPRESSÕES ARITMÉTICAS
Linguagem PHP Prof.: Sergio Pacheco Prof.: Sergio Pacheco 1 1.
Tratamento de Ficheiros
Programação Baseada em Objectos Desenho de TAD
Revisão da Linguagem C.
Introdução a Programação JAVA
PROGRAMAÇÃO I UNIDADE 1.
CADEIA DE CARACTERES (Strings)
Computação Eletrônica
1 2 Observa ilustração. Cria um texto. Observa ilustração.
Linguagem de Programação JAVA Técnico em Informática Professora Michelle Nery.
Resolução de sistemas de equações lineares
Campus de Caraguatatuba Aula 2: Somatório e Produtório
Planilha Eletrônica - Excel
Usando Perl para a extracção automática de informação a partir de corpus bruto / cru Tema 4A Pablo Gamallo Otero
18/19 de Maio de 2004Registos em Ficheiros1 Pedro Barahona DI/FCT/UNL Maio 2004.
11/12 de Maio de 2004Caracteres e cadeias1 Caracteres e Cadeias (“Strings”) Pedro Barahona DI/FCT/UNL Maio 2004.
10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 Jorge Cruz DI/FCT/UNL Introdução aos Computadores e à Programação 1º Semestre 2005/2006.
23 Novembro 2007Registos em Ficheiros - Estruturas1 Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 1º Semestre 2007/2008.
Transcrição da apresentação:

Caracteres, Cadeias (“Strings”) Registos em Ficheiros DI/FCT/UNL 1º Semestre 2004/2005

Processamento de Texto Muita informação útil, nomeadamente em tarefas de gestão, não é do tipo numérico. Por exemplo, variadas entidades (pessoas, empresas, disciplinas, departamentos, etc...) têm associado um nome que se pode querer processar (por exemplo ordenar). Este é apenas um exemplo de situações em que se pretende que os programas efectuem processamento de texto. Todas as linguagens de programação prevêem pois tipos de dados para este fim, nomeadamente Caracteres; Cadeias de caracteres (“strings”).

Caracteres Os caracteres mais utilizados (representados no código ASCII - American Standard Code for Information Interchange) incluem: Letras (52), maiúsculas (26) e minúsculas (26) Dígitos (10) Espaço e outros caracteres “visíveis” (34) ‘ “ ( ) [ ] { } , . : ; = < > + - * \ | / ^ ~ ´ ` # $ % & _ ! ? @ Caracteres de controle (32) horizontal tab (\t), new line (\n), alert (\a), ... Outros caracteres, (ç, ã, ñ, š , ø , ∞,  , Σ, ш, ך, ﭏ, غغ) só podem ser representados em códigos mais avançados e não são “suportados” em algumas linguagens de programação (em Octave, uma variável não pode ter o nome “acção”)

Cadeias de Caracteres Cadeias de caracteres são sequências (ordenadas) de caracteres. Em quase todas as linguagens, dados do tipo caracteres e cadeia (incluindo simples caracteres) são representados entre delimitadores, que podem ser aspas (“ ”) ou plicas (‘ ’). Devem sempre abrir-se e fechar-se com o mesmo tipo de delimitadores. Quando se pretende incluir um dos delimitadores no texto, podem usar-se sequências de escape nome = ‘ Maria Martins d\’Albuquerque’ ou usar-se o outro delimitador nome = “ Maria Martins d’Albuquerque” frase = ‘Ele exclamou: “Óptimo” e fugiu’

Cadeias de Caracteres e Vectores Em geral, e Octave não foge à regra, cadeias de caracteres são “implementadas” como vectores dos códigos dos caracteres. Muitas funções e operações em Octave exigem a utilização do tipo correcto. Duas funções permitem transformar Vectores em cadeias : toascii: <cadeia>  <vector> >> a = toascii(“ABC”)  a = [65,66,67] Cadeias em vectores : setstr: <vector>  <cadeia> >> b = setstr([97,98,99])  b = ‘abc’ O Octave não é muito estrito no que se refere aos tipos de dados. Por exemplo, permite operações “numéricas” com cadeias, fazendo a conversão de tipos necessária >> c = ‘abc’* 1  c = [97,98,99] Nota: Estas “facilidades” tornam difícil a detecção de erros de programação e não devem ser usadas (ou apenas com muito cuidado)

Conversão de Cadeias de Caracteres Cadeias de caracteres podem ser processados de várias formas. Para as mais comuns, existem funções predefinidas. Algumas dessas funções permitem converter cadeias de caracteres que representam números para os próprios números. Exemplo: Dada a cadeia “ 23.76 ” (com espaços), a sua conversão para um número é obtida com a função str2num. >> s = “ 23.76 “; a = str2num(s); b = 2*a  b = 47.52 É interessante comparar o resultado acima com (porquê???) >> s = “ 23.76 “; b = 2*s  b = [64,100,102,92,110,108,64,64] A conversão oposta, pode fazer-se com a função num2str.

Concatenação de Cadeias de Caracteres As cadeias podem ser concatenadas. Esta operação é utilizada para juntar numa só cadeia a informação que está dispersa por várias cadeias. Por exemplo, para juntar O(s) nome(s) próprio(s) ao(s) apelido(s) Os vários campos de um endereço (rua, nº, andar, local, etc.) O Octave tem uma função strcat, para esse efeito. Exemplo: Juntar um nome próprio e um apelido. >> np = “Rui”; ap = “Lopes”; nome= strcat(np,“ ”,ap)  nome = “Rui Lopes” De notar a utilização da cadeia com um branco (“ ”) para espaçar o nome próprio e o apelido.

Partição de Cadeias de Caracteres As cadeias podem ser “partidas” noutras mais simples. Neste caso pode haver várias formas de fazer a partição. Uma possível é através de caracteres que funcionam como separadores (tipicamente espaços). O Octave tem uma função, split, para esse efeito, criando uma matriz de cadeias, cada cadeia na sua linha, com brancos acrescentados se necessário Exemplo: Separar os nomes (próprios e apelidos) de uma pessoa. >> nome = “Rui da Costa Pina”; nms = split(nome,“ ”)  nms = “Rui ” “da ” “Costa” “Pina ”

Extracção de Cadeias de Caracteres Por vezes estamos interessados apenas em partes de uma cadeia. Uma forma comum de o fazer é indicar o índice do primeiro caracter pretendido para a subcadeia; e o comprimento da subcadeia. O Octave tem uma função, substr, para esse efeito. Por exemplo: Separar os nomes (próprios e apelidos) de uma pessoa. >> nome = “Rui da Costa Pina”; nm1 = substr(nome,1,3), nm2 = substr(nome,5,2), nm3 = substr(nome,8,5), nm4 = substr(nome,14,4),  nm1= “Rui”, nm2= “da”, nm3= “Costa”, nm4= “Pina” Os índices variam de 1 ao comprimento da cadeia. Este comprimento é obtido pela função length. >> nome = “Rui da Costa Pina”; x = length(nome)  x= 17

Comparação de Caracteres Uma operação vulgar no processamento de texto é a ordenação “por ordem alfabética”. Esta ordenação requer a comparação “alfabética” de caracteres. Esta pode ser feita através da comparação “numérica” dos códigos dos caracteres. A comparação só é fácil se os códigos usados respeitam a ordem alfabética, o que acontece em todos os códigos. Por exemplo em ASCII, o código dos caracteres “A” e “B” é, respectivamente, 65 e 66, pelo que se pode fazer a correspondência pretendida o caracter c1 “vem antes do” caracter c2  c1 < c2 Exemplo: >> teste = “a” < “b”  teste = 1

Comparação de Cadeias de Caracteres A comparação “literal” pode ser obtida a partir da comparação caracter a caracter. O Octave tem uma função, strcmp, para verificar se duas cadeias são idênticas. >> nm1 = “Rui Costa”; nm2 = “Rui Costa”; t = strcmp(nm1,nm2)  t = 1 Para o teste de precedência alfabética (designado por “<<“) o Octave não dispõe de funções predefinidas. Mas elas podem ser definidas tendo em conta a comparação caracter a caracter. Vamos pois definir uma função my_before da seguinte forma my_str_before (s1,s2) = 1 se s1 << s2 0 se s1 = s2 -1 se s1 >> s2

Comparação de Cadeias de Caracteres Dada a natureza recursiva da função my_before, esta utiliza uma função auxiliar, my_tail, para obter a “cauda da cadeia (isto é, sem o seu primeiro caracter). function t = my_str_tail(s) c = length(s); if c == 1 t =""; else t = substr(s,2,c-1); endif; endfunction; A função my_before compara os primeiros caracteres das cadeias (se existirem). Se estes forem iguais, compara as caudas das cadeias (chamada recursiva).

Comparação de Cadeias de Caracteres function b = my_str_before(s1,s2) c1 = length(s1); c2 = length(s2); if c1 == 0 & c2 == 0 b = 0; elseif c1 == 0 & c2 > 0 b = 1; elseif c1 > 0 & c2 == 0 b = -1; else % c1 > 0 & c2 > 0 if s1(1) < s2(1) b = 1; elseif s1(1) > s2(1) b = -1; else t1 = my_str_tail(s1); t2 = my_str_tail(s2); b = my_str_before(t1,t2); endif; endfunction;

Comparação de Cadeias de Caracteres A comparação de cadeias de caracteres “interpretáveis” (por exemplo, de texto em português) é mais complexa. Os problemas mais frequentes são de 3 tipos: Ocorrência de espaços (e outros caracteres brancos) “Rui Santos” = “ Rui Santos “ ??? Tratamento de letras maiúsculas e minúsculas “Rui Santos” = “RUI SANTOS “ ??? Caracteres especiais (com acentos e cedilhas) “João França” = “Joao Franca“ ??? Estes problemas têm de ser considerados no contexto apropriado (Franca e França são apelidos diferentes, ou o terminal (telemóvel) não tinha o caracter “ç” ?), e requerem algoritmos dedicados.

Comparação de Cadeias com Brancos Os caracteres brancos servem para separar os “significativos”. Os mais vulgares são os espaços, mas existem outros para mudança de linha (“\n”, “\r” ou “\f”), ou tabulação (“\t” e “\v”). No código ASCII todos têm códigos inferiores a 32 (espaço). A comparação de cadeias pode simplificar-se se a comparação for feita após normalização. Esta normalização, consiste em eliminar todos os brancos prefixos/sufixos, i.e. antes/depois do primeiro/último caracter significativo. Substituir todos os separadores (grupos de brancos, tabs, mudanças de linha, etc. por um só branco). Algumas funções predefinidas podem auxiliar na normalização, mas o Octave não tem esta função predefinida.

Substituição de Brancos por Espaços Assumindo que todos os caracteres brancos têm código inferior a 32, podemos utilizar a função my_str_remctr, indicada abaixo, para substituir todos os caracteres brancos por espaços. function t = my_str_remctr(s) for i = 1:length(s) if toascii(s(i)) < 32 t(i) = " "; else t(i) = s(i); endif; endfor; endfunction;

Eliminação de Brancos Prefixos e Sufixos O Octave dispõe de uma função (deblank) que elimina todos os espaços sufixos. A eliminação dos brancos prefixos pode igualmente usar essa função se se inverter (passá-la de trás para a frente) a cadeia. Essa inversão pode usar a função my_str_rev, indicada abaixo function r = my_str_rev(s) c = length(s); for i = 1:c r(i) = s(c-i+1); endfor endfunction;

Eliminação de Espaços Repetidos A eliminação dos espaços repetidos pode ser feita usando a função my_str_remrep, indicada abaixo. A função percorre toda a cadeia mantendo a informação (na variável booleana ultimo_branco) sobre se o último caracter era branco. Nesse caso, se o caracter for espaço não o copia (seria repetido). function t = my_str_remrep(s) j = 1; ultimo_branco = 0; for i = 1:length(s) if s(i) != " " t(j) = s(i); j = j+1; ultimo_branco = 0; elseif !ultimo_branco t(j) = s(i); j = j+1; ultimo_branco = 1; endif; endfor; endfunction;

Normalização de Cadeias de Caracteres A normalização de cadeias de caracteres pode ser feita usando a função my_str_norm, indicada abaixo, que utiliza todas as funções anteriores, da forma esperada. Primeiro, substitui os brancos por espaços. Depois elimina os espaços sufixos. Em terceiro lugar elimina os brancos prefixos (eliminando os brancos sufixos da cadeia invertida, invertendo de novo o resultado). Finalmente, os espaços repetidos são removidos. function sn = my_str_norm(s) s1 = my_str_remctr(s) s2 = deblank(s1); s3 = my_str_rev(deblank(my_str_rev(s2))); sn = my_str_remrep(s3); endfunction;

Comparação de Cadeias com Brancos A comparação de cadeias de caracteres pode ser feita usando a função my_str_norm_before, indicada abaixo, que não considera os caracteres brancos. function b = my_str_norm_before(s1,s2) sn1 = my_str_norm(s1); sn2 = my_str_norm(s2); b = my_str_before(sn1,sn2); endfunction; As diferenças podem ser exemplificadas em baixo. >> t = my_str_before(“Rui Lopes”, “ Rui Lopes”)  t = -1 >> t = my_str_norm_before(“Rui Lopes”, “ Rui Lopes”)  t = 0

Comparação com Maiúsculas/Minúsculas A comparação de cadeias de caracteres pode ser igualmente prejudicada pela existência de letras maiúsculas e minúsculas. O Octave tem algumas funções que facilitam o tratamento deste tipo de situações, nomeadamente as funções tolower e toupper, que convertem os caracteres maiúsculos / minúsculos em caracteres minúsculos / maiúsculos. >> s1 = “\n Rui \t Lopes”; s2 = “RUI lopes”; sn1 = toupper(s1), sn2 = toupper(s2), t1 = my_str_norm_before(s1,s2), t2 = my_str_norm_before(sn1,sn2)  sn1 = “\n RUI \t LOPES” sn2 = “RUI LOPES” t1 = -1 t2 = 0

Conversão entre Maiúsculas/Minúsculas As funções anteriores assumem um código ASCII, em que os caracteres brancos têm códigos abaixo de 32. Nesse código ASCII, a conversão entre maiúsculas e minúsculas pode ser feita adicionando ou subtraindo a sua diferença aos códigos respectivos. Esta diferença é 32, como pode ser verificado em >> dif = toascii(“A”) – toascii(“a”)  dif = -32 No entanto, a utilização destes valores pode ser problemática, se forem usados outros códigos. É da responsabilidade da implementação da linguagem interpretar ter em atenção os códigos usados (que podem não ser ASCII) e disponibilizar primitivas independentes desses códigos.

Conversão independente do Código Algumas dessas primitivas são isalpha(s) 1 se s for alfabético (maiúscula ou minúscula) islower(s) 1 se s for uma minúscula isupper(s) 1 se s for uma maiúscula isdigit(s) 1 se s for um dígito isalnum(s) 1 se s for dígito ou alfabético ispucnt 1 se s for um caracter de pontuação iscntrl(s) 1 se s for caracter de controle Desta forma as funções poderão ser rectificadas para se tornarem independentes do código usado para representação dos caracteres. Em particular, o teste toascii(s(i)) < 32 pode/deve ser substituido por iscntrl(s2)

Cadeias com Caracteres Especiais Os caracteres com cedilhas e acentos, típicos do português, não fazem parte do código ASCII básico, e os seus códigos em ASCII estendido não respeitam a ordem “natural”. Por exemplo, como os códigos dos caracteres “a”, “s” e “ã” são, respectivamente 97, 115 e 227, o nome João está alfabeticamente após José, ao contrário do que acontece com Joao. Uma forma de manter a ordenação pretendida é utilizar, para efeitos de ordenação, as cadeias com os caracteres acentuados substituídos pelos caracteres não acentuados. O Octave dispõe de uma função (strrep) que substitui numa cadeia base, todas as de uma (sub)cadeia por outra. >> s1 = “João”; s2 = strrep(s1,”ã”,”a”)  s2 = “Joao”

Registos em Ficheiros Muita informação alfanumérica está registada em ficheiros, na forma de “registos”. Por exemplo, numa base de dados da empresa, são mantidos ficheiros com informação sobre os empregados da empresa. Muitas aplicações (de gestão) consistem em ler ficheiros e criar outros com a informação devidamente processada. Por exemplo: ler um ficheiro de empregados e escrever outro, apenas com os empregados com vencimento superior a 1000 €.

Leitura de Ficheiros A primeira questão a resolver consiste no tratamento dos caracteres brancos em cadeias de caracteres. Isto porque há duas formas típicas de armazenamento dessas cadeias: Comprimento Fixo: As cadeias têm sempre o mesmo número de caracteres (sendo usados espaços se necessário); Comprimento Variável: As cadeias têm o número de caracteres necessários, sendo necessários caracteres separadores, tipicamente tabs (horizontais).

Leitura de Ficheiros Por exemplo, “Pedro Vieira” pode ser codificado Comprimento Fixo: Com 5+1+6 = 12 caracteres (incluindo o espaço), mais 13 espaços, para permitir cadeias de comprimento 25, que podem armazenar nomes com até 25 caracteres (incluindo espaços); Comprimento Variável: Apenas com os 12 caracteres necessários, sendo separado do vencimento por um tab horozontal (‘\t’).

Leitura de Ficheiros Em Octave (e em C) os dois tipos de codificação requerem instruções de leitura padronizada (com templates) diferentes. Comprimento Fixo: Utiliza-se um template “%nc” em que n é o número de caracteres a ler; Comprimento Variável: Utiliza-se um template “%s”; Neste último caso, levanta-se um problema: O template ‘%s’, não lê nem caracteres brancos nem espaços. Assim, o nome “Pedro Vieira” seria lido não como 1, mas sim como 2 cadeias. Em geral, ter-se-ia de conhecer o número de nomes (próprios, apelidos e partículas de ligação). Isto pode ser evitado com o uso de espaços especiais (“non break spaces” - ASCII 160), que são lidos como quaisquer outros caracteres, mas são impressos como espaços .

Leitura de Ficheiros Caso seja necessário, pode converter-se um ficheiro noutro, convertendo-se todos os espaços em espaços especiais, com a função abaixo: function x = rem_sp(f_in_name, f_out_name); [f_in, msg] = fopen(f_in_name , "r"); [f_aux,msg] = fopen(f_out_name, "w"); [ch, count] = fscanf(f_in,"%1c","C"); while !feof(f_in) if ch == " " ch = setstr(160); endif; fprintf(f_aux, "%1c", ch); endwhile; fclose(f_in); fclose(f_aux); endfunction;

Leitura de Ficheiros Comprimento Fixo: Cada linha do ficheiro, assumindo-se que um nome é guardado com 25 caracteres, pode ser lida com as seguintes instruções de leitura padronizada, fscanf: [cod, count] = fscanf(fid,"%i","C"); [nome, count] = fscanf(fid,"%25c","C"); [venc, count] = fscanf(fid,"%f","C"); [data, count] = fscanf(fid,"%s","C"); ou numa só instrução [cod,nome,venc,data,count]=fscanf(fid,"%i%25c%f%s","C"); 610 Paulo Fernandes Lopes 2341.36 15/04/1996

Leitura de Ficheiros Comprimento Variável: Neste caso, quer o nome quer a data podem ser lidos com o template “%s” da instrução fscanf, podendo o registo de um empregado ser lido quer na forma [cod, count] = fscanf(fid,"%i","C"); [nome, count] = fscanf(fid,"%s","C"); [venc, count] = fscanf(fid,"%f","C"); [data, count] = fscanf(fid,"%s","C"); quer numa só instrução [cod,nome,venc,data,count]=fscanf(fid,"%i%s%f%s","C"); 610 Paulo Fernandes Lopes 2341.36 15/04/1996

Escrita de Ficheiros A escrita de ficheiros depende igualmente do formato utilizado para as strings. Em comprimento fixo, o registo pode ser escrito como fprintf(fid, "%3i", cod); fprintf(fid, "%-25s", nome); fprintf(fid, "%7.2f", venc); fprintf(fid, "%11s", data); fprintf(fid, "%c", “\n”); ou numa só instrução, como anteriormente. Notar ainda que O sinal – (em %-25s) justifica, à esquerda, o campo nome. Após o último campo deve ser escrito um caracter (‘\n’), para mudança de linha 610 Paulo Fernandes Lopes 2341.36 15/04/1996

Escrita de Ficheiros Em comprimento variável, o registo de um empregado pode ser escrito como fprintf(fid, "%i\t", cod); fprintf(fid, "%s\t", nome); fprintf(fid, "%7.2f\t", venc); fprintf(fid, "%s\n", data); ou numa só instrução, como anteriormente. Notar, que Após cada campo, deve ser escrito o tab (‘\t’) de separação, excepto no último campo, após o que se escreve o caracter (‘\n’) Alguns templates podem ser fixos, (por exemplo, "%7.2f\t”) para evitar as convenções por omissão do Octave. 610 Paulo Fernandes Lopes 2341.36 15/04/1996

Selecção de Registos Podemos agora abordar o problema colocado anteriormente: ler um ficheiro de empregados e escrever outro, apenas com os empregados com vencimento superior a 1000 euros. Naturalmente o programa dependerá de os ficheiros serem lidos e escritos em formato fixo ou variável. Assumiremos que esta diferença apenas se reflectirá no campo “nome”, já que o campo “data” não contem espaços e pode ser lido em formato cadeia (“%s”) sem problema.

Selecção de Registos Eis a versão para formato fixo. [f_in, msg_in ] = fopen("empresa_in_fix.txt", "r"); [f_out, msg_out] = fopen("empresa_out_fix.txt", "w"); [cod,nome,venc,data,ct] = fscanf(f_in,"%i%25c%f%s","C"); while !feof(f_in) if venc > 1000 fprintf(f_out,"%3i%-25s%7.2f%11s", cod,nome,venc,data); fprintf(f_out, "%c", "\n"); endif; endwhile; fclose(f_in); fclose(f_out);

Selecção de Registos E eis a versão para formato variável. rem_sp("empresa_in_var.txt", "empresa_aux_var.txt"); [f_aux, msg] = fopen("empresa_aux_var.txt", "r"); [f_out, msg] = fopen("empresa_out_var.txt", "w"); [cod,nome, venc, data, count] = fscanf(f_aux,"%i%s%f%s","C"); while !feof(f_aux) if venc > 1000 fprintf(f_out, "%i\t%s\t%7.2f\t%s\n", cod,nome,venc,data); endif; endwhile; fclose(f_aux); fclose(f_out);