Você está na página 1de 18

Programação 1, 2020/2021

Programação 1
18. Ficheiros

FEUP, DEI
Programação 1, 2020/2021

Ficheiros ficheiro.txt

• Armazenamento persistente de informação


• Em quase todos os Sistemas Operativos
modernos os ficheiros estão organizados
num vetor unidimensional de bytes
• São associados a um nome através do qual
podem ser acedidos
• Operações típicas sobre um ficheiro: criar,
modificar de atributos, abrir, ler e modificar
conteúdo, guardar alterações e fechar


2

FEUP, DEI
Programação 1, 2020/2021

Ficheiros de texto
Informação é guardada sob a forma de linhas de texto,
separadas por um caráter terminador de linha, '\n’

Os elementos do ficheiro são acedidos sequencialmente,


em posições consecutivas

Exemplo dos bytes guardados num ficheiro de texto

código representação
ASCII textual

FEUP, DEI
Programação 1, 2020/2021

Ficheiros binários
Organizados em elementos de dimensão fixa que podem
ser de tipos simples ou estruturados (registos). Portanto,
nos ficheiros binários não há marcas de "fim de elemento",
porque o fim de cada elemento é sempre conhecido.

Inteiros representados por dois bytes: registos com string de quatro carateres e
{ 12, 1283, 128, 0, 15371 } inteiro representado por dois bytes:
{{"ABC",129}, {"P1",1152}}

12 1283 "ABC" 129

"P1" 1152
15371
4

FEUP, DEI
Programação 1, 2020/2021

Utilização
Os ficheiros de texto podem ser editados e
inspecionados com qualquer editor de texto. .txt .c .html

Contudo, só devem ser usados quando os


dados armazenados sofrem poucas alterações .md .json
e a sua quantidade é moderada.

Os ficheiros binários costumam usar-se


quando temos grandes quantidades de dados .bin .exe .docx

que necessitam de ser operados rapidamente


em acesso direto e sofrem contínuas alterações, .mp3 .jpg

não sendo prático estarmos a basearmo-nos em


cópias do ficheiro.

FEUP, DEI
Programação 1, 2020/2021

Operações com ficheiros

fprintf | fwrite fopen

ficheiro

fscanf | fread fclose

programa disco

buffer
6

FEUP, DEI
Programação 1, 2020/2021

FILE
O "file buffer" é um registo designado FILE, que contém
(entre outros) um campo vetor de carateres, um campo para
indicar o estado de preenchimento do buffer e um campo de
nome que irá estar associado a um dado ficheiro.

FILE *f

FEUP, DEI
Programação 1, 2020/2021

fopen e fclose
FILE *fopen(char *filename, char *mode) "r" – para leitura (read)
int fclose(FILE *f) "w" – para escrita (write)
"a" – para acrescentar
FILE *f; (append)
char nomef[100]; "b" – formato binário
printf("nome do ficheiro? "); (binary)

scanf("%s", nomef);
f=fopen(nomef,"w");
...
fclose(f);

Para guardar as alterações sem fechar o ficheiro:


int fflush(FILE *f)

FEUP, DEI
Programação 1, 2020/2021

fprintf e fscanf
Ficheiros de texto

int fprintf(FILE *f, string_de_formato [, expr1, …, exprn])


int fscanf(FILE *f, string_de_formato, &var1 [,&var2 …, &varn])

FILE *f;
int numero;
f=fopen("exemplo.txt","w");
scanf("%d", &numero);
fprintf(f, "um numero lido: %d\n", numero);
fclose(f);

fprintf e fscanf comportam-se exatamente como printf e scanf,


respetivamente, só que na escrita e leitura referem-se a um ficheiro
em vez de escreverem no ecrã e lerem do teclado.

10

FEUP, DEI
Programação 1, 2020/2021

Exemplo ficheiro de texto


#include <stdio.h>

int main()
{
int i,k;
char *cidade[4] = {"Porto", "Aveiro", "Coimbra", "Lisboa"};
float temp[4] = {12.5, 11.8, 12.2, 14};
FILE *fout; /* declara variável de ficheiro */

fout = fopen("exp.txt", "w"); /* abre ficheiro para escrita*/

for (i = 0; i < 4; i++)


fprintf(fout,"%s %f\r\n", cidade[i], temp[i]);

fclose(fout);
printf("Escrita do ficheiro terminada\n");
}

11

FEUP, DEI
Programação 1, 2020/2021

Controlo de erros
#include <stdio.h>
int main()
{
int i,k;
char *cidade[4] = {"Porto", "Aveiro", "Coimbra", "Lisboa"};
float temp[4] = {12.5, 11.8, 12.2, 14};
FILE *fout; /* declara variável de ficheiro */

fout = fopen("exp.txt", "w"); /* abre ficheiro para escrita */

if (fout == NULL) { /* se apontador inválido */


printf("Impossível criar o ficheiro\n");
return 1; /* termina */
}

for (i = 0; i < 4; i++) {


k = fprintf(fout,"%s %f\r\n", cidade[i], temp[i]);
printf("%d\n", k);
}

fclose(fout);
printf("Escrita do ficheiro terminada\n");
}

12

FEUP, DEI
Programação 1, 2020/2021

fgetc e fputc
Ficheiros de texto

int fgetc(FILE *f)


int fputc(int c, FILE *f)

int c;
FILE *ifp, *ofp;

c = fgetc(ifp); /* ler um caracter */


fputc(c, ofp); /* escrever um caracter */

São funções correspondentes a getchar() e putchar(c) mas que


admitem a especificação do ficheiro

13

FEUP, DEI
Programação 1, 2020/2021

fread e fwrite
Ficheiros binários

int fread(void *ptr, int size, int n, FILE *fich)


int fwrite(void *ptr, int size, int n, FILE *fich)

#include <stdio.h>
int main()
{
short v[4] = {1200, 200, 56, 14};
FILE *f;
f = fopen("int.bin", "wb");
fwrite(v, sizeof(short), 4, f);
fclose(f);
printf("Escrita do ficheiro terminada\n");
}

14

FEUP, DEI
Programação 1, 2020/2021

Acesso direto: fseek


Os ficheiros binários são geralmente geridos em modo direto, isto é, acedendo
diretamente a qualquer elemento dentro do ficheiro. A linguagem C
disponibiliza uma rotina que permite modificar a posição do ficheiro:
int fseek(FILE *fich, long salto, int origem)
i) O parâmetro fich é a variável de ficheiro.
ii) O parâmetro salto designa o valor em bytes que pretendemos "andar"
quer para a frente quer para trás relativamente à origem.
iii) O parâmetro origem tem três valores possíveis, representados pelas
seguintes constantes simbólicas:
SEEK_SET: início do ficheiro;
SEEK_CUR: posição corrente do ficheiro;
SEEK_END: fim do ficheiro.

15

FEUP, DEI
Programação 1, 2020/2021

ftell e rewind
a posição corrente, em bytes, dentro de um ficheiro é dada por:
long ftell(FILE *fich)

sempre que queremos regressar ao início de um ficheiro usamos o procedimento:


void rewind(FILE *fich)

#include <stdio.h>
#include <string.h>

int main()
{
int n; FILE *f;
f = fopen("real.dat", "rb");
fseek(f,0, SEEK_END); /* vai para o fim */
n = ftell(f);
printf("Bytes: %d; Reals: %d\n", n, n/sizeof(float));
fclose(f);
}

16

FEUP, DEI
Programação 1, 2020/2021

Argumentos na linha de comando


int main(int argc, char *argv[])

A função main comporta-se como o programa principal, é a primeira função a


ser invocada e a partir da qual todas as restantes funções são invocadas.

É possível passar informação de entrada tal como para qualquer outra função.

argc (número)

argv argv[0] " \0"


argv[1] " \0"
.. ..
argv[argc-1] " \0"

17

FEUP, DEI
Programação 1, 2020/2021

Exemplo linha de comando


#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {


int i,k;
char cidade[4][8] = {"Porto", "Aveiro", "Coimbra", "Lisboa"}, c;
float temp[4] = {12.5, 11.8, 12.2, 14};
FILE *fp;
if (argc < 3){ /* número de argumentos é suficiente? */
printf("Uso: %s ficheiro modo\n", argv[0]);
return 1;
}
fp = fopen(argv[1], argv[2]);
if(argv[2][0] == 'w'){
for (i = 0; i < 4; i++)
fprintf(fp,"%s %f\r\n", cidade[i], temp[i]);
} else
if(argv[2][0] == 'r'){
/* lê do ficheiro... */
} else
printf("Operação não reconhecida!\n");
fclose(fp);
printf("Utilização do ficheiro terminada\n");
} 18

FEUP, DEI
Programação 1, 2020/2021

Avisos
• Aula prática 10
– Preparar problema 2 (disponível no Moodle)

• Microteste 3
– Exemplos disponibilizados no Moodle

• Sessões de estudo acompanhado


– Última: 12/jan no horário 10h-12h
– Link no Moodle

19

FEUP, DEI

Você também pode gostar