1 Topicos de C
1 Topicos de C
1 Topicos de C
(Tópicos)
Conteúdos
1- Algoritmos
2- Introdução à Linguagem C & Estruturas de Controlo
3- Funções
4- Vectores e Matrizes
5- Apontadores (Ponteiros)
6- Estruturas de dados
7- Ficheiros
Programação Cap. 1
1 Capítulo 1. - Algoritmos
Programação
Programação de um computador
Fase de Implementação
- Solução específica (programa) – Traduzir o algoritmo numa linguagem
de programação específica: Pascal, C Basic, java, Cobol, ...
- Prova – Fase em que o computador segue as instruções. Comprovar os
resultados e fazer as correcções se necessário.
- Uso – utilizar o programa.
DEI E.S.T.G./I.P.Leiria 1
Programação Cap. 1
Linguagem de programação:
- Conjunto de regras, símbolos e palavras especiais utilizados para construir um
programa.
- Composição:
o Uma terminologia ou conjunto de termos, palavras e sinais, que assumem
determinados significados (semântica);
o Um conjunto de regras que estipulam o uso correcto dos termos, para
construir enunciações válidas (sintaxe).
1 - Analisar o problema
- Compreender o problema. Compreender o que se dá (dados de entrada) e o que
se pede (dados de saída).
- Especificar os formatos de entrada e os de saída.
DEI E.S.T.G./I.P.Leiria 2
Programação Cap. 1
Exemplo prático:
Pretende-se encontrar a média ponderada de três exames. Os dados são inseridos na
seguinte forma, nota do exame e respectivo peso.
- Aproximação bottom-up
Esta técnica, menos usada, segue o sentido inverso da primeira.
Pseudocódigo
- Linguagem próxima da fala.
- Sem redundância nem ambiguidades.
- Palavras chaves habituais:
o INÍCIO / FIM
o LER / ESCREVER
o SE ... ENTÃO ... SENÃO ...
o REPETIR ... ATÉ QUE ...
o ENQUANTO ... FAZER ...
DEI E.S.T.G./I.P.Leiria 3
Programação Cap. 1
Exemplo
* programa que lê um número, calcula o seu dobro e apresenta o resultado
INÍCIO
LER a
b=a*2
ESCREVER “O dobro de a é b”
FIM
- Utilizar uma hierarquia de tabulação (com indentação) par ter uma maior
legibilidade do algoritmo.
- O símbolo * é utilizado par introduzir um comentário no algoritmo.
Fluxogramas
Fluxogramas são diagramas que mostram as operações a realizar e a sequência
segundo a qual as diferentes operações que constituem o algoritmo deverão ser realizadas.
O símbolos padrão são os seguintes:
- Processamento
- Leitura / escrita
- Linhas de fluxo
- Conector
- Decisão
- Decisão múltipla
- Início / fim
Exemplo de Fluxograma:
DEI E.S.T.G./I.P.Leiria 4
Programação Cap. 1
DEI E.S.T.G./I.P.Leiria 5
Programação Cap. 2
Capítulo 2.
Introdução à Linguagem C - Estruturas de Controlo
Características da linguagem C:
- Rapidez;
- Simples;
- Alto grau de portabilidade;
- É de uso geral;
- Gera um código executável (Objecto);
- Permite total interacção com o sistema operativo;
- Possui uma sintaxe e poucos comandos;
- É uma linguagem estruturada e modular;
- Permite tratamento de estruturas de dados;
- Bibliotecas poderosas;
- Evolução (Linguagens Orientadas por Objectos).
DEI E.S.T.G./I.P.Leiria 1
Programação Cap. 2
Tipos de dados:
- char caracter (1 byte).
- int inteiro (2 ou 4 bytes).
- float número de vírgula flutuante (normalmente 4 bytes).
- double número de vírgula flutuante de precisão dupla (normal. 8 bytes).
DEI E.S.T.G./I.P.Leiria 2
Programação Cap. 2
Inicialização:
- Tipo_da_variável nome_da_variável = constante;
- Exemplos:
o char ch=’d’;
o char ch1=4;
o int x1, x2, y, z = 0;
o float pi=3.14156;
- Constante simbólicas:
o #define PI 3.14156
o #define IVA 0.19
Biblioteca “stdio.h”:
- getchar()
- putchar()
- gets()
- puts()
- scanf()
- printf()
Exemplos:
Saída formatada:
int printf(s_formato, arg1, arg2,...)
DEI E.S.T.G./I.P.Leiria 3
Programação Cap. 2
As Flags são:
- - a saída é justificada à esquerda.
- + é mostrado o sinal dos números.
- ‘ ‘ os números positivos são precedidos de um espaço.
- # aplica-se aos caracteres x, X ou o.
- O especificador de largura do campo:
o Um inteiro decimal não começado por zero. A saída é mostrada com espaços
branco a encher todo o campo.
o Um inteiro decimal começado por zero. A saída é mostrada com zeros à esquerda
a encher todo o campo.
o O caracter asterisco (*). O valor do próximo argumento (que deverá ser um
inteiro) é usado como largura do campo.
- A precisão, especificada com o ponto decimal (.), podendo ser seguido de um número:
o Se especificado aos caracteres e, E, f, F, g, G, específica o número de dígitos a
ser mostrado à direita do ponto. Se o ponto é usado sozinho específica que a
precisão é 0;
o Se aplicado ao caracter de conversão s, específica o número de caracteres a serem
mostrados.
- Modificador de comprimento h, l, L:
o O “h” indica que o argumento correspondente deve ser escrito como um short ou
unsigned short.
o O “l” aplicado aos caracteres o, u, x, X, d, e b, indica que o argumento é do tipo
long, ou unsignel long.
o O “L” aplicado aos caracteres e, E, g, ou G, específica que o argumento é do tipo
long double.
Exemplo:
#include <stdio.h>
main()
{
printf(“|%5.4d| |%-5.3s| |%5.0f|\n”,123,”nome”,45.6);
printf(“|%+5d| |%+d| |% 5d| |% 5d| \n”,123, -123, 123, -123);
DEI E.S.T.G./I.P.Leiria 4
Programação Cap. 2
Saída:
| 0123| |nom | | 46|
| +123| | -123| | 123| | -123|
| O17| | xf| | 15.|
|00015| | 15| | 15.00|
Entrada formatada:
Operadores em linguagem C:
Aritméticos:
+ adição;
- subtracção;
* multiplicação;
/ divisão;
% módulo (resto da divisão inteira).
Manipulação de bits:
<< desloca para a esquerda os bits;
>> desloca para a direita os bits;
& conjunção AND binário;
^ XOR (ou exclusivo binário);
| disjunção OR (ou inclusivo binário).
Lógicos:
&& AND (e lógico);
|| OR (ou lógico);
! negação (NOT).
Atribuição:
= atribuição;
*= atribuição com multiplicação;
/= atribuição com divisão;
%= atribuição com resto da divisão inteira (modulus);
+= atribuição com adição;
-= atribuição com subtracção;
<<= atribuição com deslocamento binário para esquerda;
>>= atribuição com deslocamento binário para direita;
&= atribuição com AND (binário);
DEI E.S.T.G./I.P.Leiria 5
Programação Cap. 2
Exemplos:
- Atribuição:
<variável> = <variável> <operador> <variável>
x = y + 3;
- Atribuição múltipla:
x = y = z = 47;
Ordem da atribuição.
- Atribuições compostas:
x+=1; x=x+1;
y*=2+3; y=y*(2+3);
a-=b+1; a=a-(b+1);
k/=12; k=k/12;
r%=2; r=r%2;
DEI E.S.T.G./I.P.Leiria 6
Programação Cap. 2
Valores lógicos:
Em C o valor lógico Falso é representado por 0 (zero) e tudo o que for representado por um
valor diferente de zero representa o valor lógico Verdadeiro.
Operadores Associatividade
( ) [ ] -> . Esquerda para a direita
! ~ ++ -- Direita para a esquerda
-(unário) (cast) *(unário)
&(unário)
(tipo) sizeof
* / % Esquerda para a direita
+ - “”
<< >> “”
< <= > >= “”
= = != “”
& “”
^ “”
| “”
&& “”
|| “”
?: Direita para a esquerda
= += -= *= /= %= &= Direita para a esquerda
^=
|= <<= >>=
, Esquerda para a direita
Modeladores (casts):
Para forçar um tipo especificado
(tipo) expressão;
exemplo:
#include <stdio.h>
int main ()
{
int num=10;
float f;
f=(float)num/7;
printf(“%f”,f); /* 1.42857 */
return (0);
}
DEI E.S.T.G./I.P.Leiria 7
Programação Cap. 2
char ch;
int i;
float f;
double d;
result = (ch / i) + ( f * d ) – ( f + i );
double
- Instrução IF:
if (expr)
instrução;
ou
if (expr)
instrução1;
else
instrução2;
DEI E.S.T.G./I.P.Leiria 8
Programação Cap. 2
- Instrução SWITCH:
switch (expressão) {
case constante1 : instrução;
break;
case constante2 : instrução;
break;
...
default : instrução;
break;
}
- Ciclo WHILE:
while (expr)
instrução;
- Ciclo DO – WHILE:
do
Instrução;
while (expr);
DEI E.S.T.G./I.P.Leiria 9
Programação Cap. 2
- Ciclo FOR:
DEI E.S.T.G./I.P.Leiria 10
Programação Cap. 3
Capítulo 3.
Funções
3.1 Definição
Uma função é um módulo independente de código, que tem um nome e executa uma tarefa específica.
Exemplos:
int le_digito(void)
{
int c;
do
c=getchar();
while(c<’0’ || c>’9’);
return c;
}
Nota:
Condição A Condição B Condição A || Condição B
Falso Falso Falso
Falso Verdadeiro Verdadeiro
Verdadeiro Falso Verdadeiro
Verdadeiro Verdadeiro Verdadeiro
- A instrução return retorna automaticamente o tipo dos dados correcto (“cast” automático).
- Uma função pode ter várias instruções return, mas só um return é executado:
DEI E.S.T.G./I.P.Leiria 1
Programação Cap. 3
Características:
- Definição da função: O código da função (cabeçalho + corpo).
- Declaração/protótipo: Cabeçalho da função, seguido de ponto e vírgula (;). Informa o compilador que a
função existe. Desta forma a função pode ser definida depois a sua invocação.
- Os argumentos de uma função são as variáveis, constantes ou expressões colocadas entre parênteses da
função aquando da chamada desta.
- Os parâmetros são as variáveis colocadas entre os parênteses da função aquando da definição da função.
- Os argumentos de invocação da função devem existir na mesma quantidade e mesma ordem dos parâmetros da
definição da função. No entanto os nomes podem ser diferentes.
- As variáveis declaradas dentro da função são variáveis locais e são apenas visíveis dentro da função. Após
terminar a execução de uma função essas variáveis locais são destruídas (memória libertada).
A função troca(int n1, int n2) somente faz a troca dentro da própria função com cópias n1 e n2 das variáveis a e b e
liberta essas cópias no fim da execução da função.
DEI E.S.T.G./I.P.Leiria 2
Programação Cap. 3
- Vectores como argumento de uma função => passagem por “referência” automática:
#include <stdio.h>
#include <conio.h>
void troca(int Vector[]);
void main(void)
{
int Vector[]={1,2}; A inicialização faz com que a dimensão do Vector seja 2.
troca(Vector); O endereço do Vector é passado para a função troca.
printf("\n Vector[0]=%d Vector[1]=%d",Vector[0],Vector[1]); Troca efectuada!
getch();
}
temp=Vect[0];
Vect[0]=Vect[1];
Vect[1]=temp;
}
Notas:
a) O endereço do Vector é o próprio nome Vector = = &Vector[0].
b) Vector[i] *(Vector+i)
2)
main ()
{
int x; Variáveis distintas. Não há conflito!
...
}
func( )
{
int x;
...
x=1;
...
}
DEI E.S.T.G./I.P.Leiria 3
Programação Cap. 3
3)
func(float x) Errado!
{
float x;
...
}
4)
func( )
{
...
x=1; Errado!
...
} Variável global com visibilidade deste ponto para baixo.
int x;
DEI E.S.T.G./I.P.Leiria 4
Programação Cap. 4
Exemplo:
DEI ESTG/IPLeiria 1
Programação Cap. 4
v &v[0]
Funções e vectores:
Se o argumento de uma função for um vector, então, este é passado automaticamente por referência (ver Cap.1
Funções)! No entanto, a função desconhece a dimensão do vector.
Exemplo:
#include <stdio.h>
#include <conio.h>
#define DIM 4
Resultado no ecrã:
v[0]+W[0]=6
v[1]+W[2]=6
v[2]+W[4]=6
v[3]+W[6]=6
DEI ESTG/IPLeiria 2
Programação Cap. 4
Função printf:
Resultado no ecrã:
Uma String é uma cadeia de caracteres!
Uma String é uma cadeia de caracteres!
DEI ESTG/IPLeiria 3
Programação Cap. 4
Função puts:
Resultado no ecrã:
Uma String é uma cadeia de caracteres!
Uma String é
uma cadeia de caracteres!
char Nome[100];
scanf(“%s”,Nome); Nome sem & e só consegue ler uma única palavra.
Um printf de um nome completo (com mais de que uma palavra) resultaria na impressão de somente o 1º nome. Leitura
até <espaço>, <tab>, ou <enter>.
Função gets:
char Nome[100];
gets(Nome); Leitura de vários caracteres até encontrar o <enter>
puts(Nome);
/*Comprimento de um String*/
int strlen(char s[]) int strlen(char *s)
{
int i=0;
while (s[i]!=’\0’)
i++;
return i;
}
DEI ESTG/IPLeiria 4
Programação Cap. 4
#include <string.h> tem um conjunto de funções para manipulação de Strings. As mais utilizadas são:
strlen Devolve o comprimento de uma String.
strcpy Copia uma String para outra.
strcat Concatenação de Strings.
strcmp Comparação alfabética de Strings.
stricmp Comparação de Strings com ignore case.
strchr Procura um caracter numa String.
strstr Procura uma String dentro de outra.
strlwr Converte todos os caracteres de uma String para minúsculas
strupr Converte todos os caracteres de uma String para maiúsculas.
Exemplo de matriz:
#define DIM 4
...
int m[DIM][DIM];
int M[3][4];
M é um vector com 3 elementos (cada elemento é um vector de 4 inteiros).
M[i] é um vector com 4 inteiros.
M[i][j] é um inteiro que está na posição da linha i e da coluna j do vector M.
sizeof(v) = = 2 * 3 * (sizeof(int))
v[0] &v[0][0]
v[1] &v[1][0]
DEI ESTG/IPLeiria 5
Programação Cap. 4
Exemplo 1:
Void soma_matriz_quadrada(int M1[][MAX], int M2[][MAX], int Msoma[][MAX])
{
int i,j;
for (i=0; i<MAX; i++)
for (j=0; j<MAX; j++)
Msoma[i][j]=M1[i][j]+M2[i][j];
}
Exemplo 2:
/* JOGO DO GALO!*/
#include <stdio.h>
#include <conio.h>
#define DIM 3
#define ESPACO ' '
void main(void)
{
char Galo[DIM][DIM];
int x,y;
char c='O';
int n_jogadas=0;
ini(Galo);
while (n_jogadas<DIM*DIM)
{
mostra(Galo);
printf("\nIntroduza a posição do Jogo Linha Coluna: ");
scanf("%d %d",&x,&y);
x--;y--;
if (Galo[x][y]==ESPACO)
{
Galo[x][y]= c = (c = = 'O')?'X':'O';
n_jogadas++;
}
else
printf("Posição já ocupada\nJogue novamente!\n");
}
mostra(Galo);
getch();
}
DEI ESTG/IPLeiria 6
Programação Cap. 4
DEI ESTG/IPLeiria 7
Programação Cap. 5
Cap. 5 – Apontadores
5.1 Definição
Declaração de apontadores (ponteiros) com o símbolo *.
int *p; p é uma variável do tipo apontador para inteiros, ou seja, p é uma variável que irá
conter o endereço de uma variável do tipo inteiro.
Notações:
int *p; int* p; int * p;
int* x,y; x é um apontador mas y não é um apontador!
Exemplo:
int x, y, *p = &x;
↑_ Apontador p inicializado com o endereço de memória da variável x.
Diz-se que p aponta para x!
x = -9;
y = *p; Atribui a y o conteúdo da posição para onde p aponta (ou seja –9).
x p y
-9 101 -9
101 ... 256 ... 533
Regras fundamentais:
Regra 2: Um apontador aponta para um objecto do mesmo tipo (sizeof(*p)) ou para constante NULL.
Regra 3: Um apontador p tem uma localização (&p, onde ele próprio está guardado) um conteúdo (p, o
que se guarda em p) e um valor indirecto (*p, o que é guardado no endereço apontado por p).
Erros comuns:
int *p;
*p = 5; ERRADO!
DEI ESTG/IPLeiria 1
Programação Cap. 5
int *p = NULL;
*p = 1; ERRADO!
int vect[20];
vect = p; ERRADO!
vect++; ERRADO!
Operadores unários * e & têm maior precedência que os operadores aritméticos básicos. Exemplo:
int x, *p, y;
x = 2;
p = &x;
y = *p+7; y terá o valor 9! *p+7 = = (*p)+7
#include <stdio.h>
#include <conio.h>
void main(void)
{
int Vector[]={1,2}, *p;
p = Vector; ou p = &Vector[0]
printf("\n p = = %d *p = = %d",p,*p);
p = p+1;
printf("\n p = = %d *p = = %d",p,*p);
getch();
}
Resultado no ecrã:
p = = 126478 *p = = 1
p = = 126479 *p = = 2
Algumas propriedades:
p = Vector p = &Vector[0]
*(p + n) = = Vector[n]
p ± n endereço ± (n * sizeof (*p))
p+n = =&Vector[n] então p = = Vector e
*(p + n) *(Vector +n) = = Vector[n] p[n]
Nota: *(Vector +n) = = *(n + Vector) = = n[Vector]
Exemplo:
#include <stdio.h>
#include <conio.h>
void main(void)
{
int v[]={1,2}, *p=v;
DEI ESTG/IPLeiria 2
Programação Cap. 5
Resultado no ecrã:
v[0] = = 1 p[0] = = 1 *(p+0) = = 1 *(v+0) = = 1
v[1] = = 2 p[1] = = 2 *(p+1) = = 2 *(v+1) = = 2
#include <stdio.h>
#include <conio.h>
void main(void)
{
char *string = "ola!!";
printf("\n strlen=%d",strlen(string));
getch();
}
Resultado no ecrã:
strlen = 5
#include <stdio.h>
#include <conio.h>
void main(void)
{
char *linha[2]={"1a linha", "2a linha"};
char *s;
puts(linha[0]);
puts(linha[1]);
s=linha[0];
linha[0]=linha[1];
linha[1]=s;
puts(linha[0]);
puts(linha[1]);
getch();
}
Resultado no ecrã:
1a linha
2a linha
2a linha
1a linha
DEI ESTG/IPLeiria 3
Programação Cap. 5
#include <stdio.h>
#include <conio.h>
void main(void)
{
int vect[2]={11,22}, * p=vect;
incr_ender(&p);
printf("\n%d",*p);
incr_valor(&p);
printf("\n%d",*p);
getch();
}
Resultado no ecrã:
22
23
A função void free(void *apt) liberta a memória previamente reservada e apontada por apt.
Nota: free(NULL) não faz nada!
Exemplo:
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <string.h>
void main(void)
{
char *v, buf[81];
int comp;
comp=strlen(gets(buf));
v=(char *)malloc(comp+1);
DEI ESTG/IPLeiria 4
Programação Cap. 5
if (v!=NULL) {
strcpy(v,buf);
printf("\nEndereco v=%d\nConteudo endereco =",v);
puts(v);
free(v);
}
else
printf("\n Impossivel alocar memoria!\n");
getch();
}
DEI ESTG/IPLeiria 5
Programação Cap. 6
Cap. 6 – Estruturas
6.1 Definição
Uma estrutura é um agrupamento de várias variáveis que podem ser de diferentes tipos. A estrutura está
referenciada por um nome e contém membros ou campos.
struct nome_da_estrutura
{
tipo1 campo1, campo2;
...
tipon campon;
};
Exemplo:
struct Data
{int Dia;
char Mês[12];
int Ano;
};
struct Aniversario
{char Nome[101];
struct Data quando;
};
struct nome_da_estrutura
{
tipo1 campo1, campo2;
...
tipon campon;
} v1, v2, ... , vn;
Exemplo:
struct Data
{int Dia;
char Mes[12];
int Ano;
};
struct Aniversario
{char Nome[101];
struct Data quando;
} Amigo[13], Temp, *Ptr_aniversario;
DEI ESTG/IPLeiria 1
Programação Cap. 6
Os membros das estruturas são acedidos através do operador membro de estrutura (.), da seguinte forma:
Temp.quando.Dia = 12;
scanf(“%d”,&Temp.quando.ano);
gets(Temp.Nome);
strcpy(Temp.Nome,”Pedro”);
strcpy(Temp.quando.Mes,”Abril”);
printf(“Data: %d/%s/%d”, Amigo[2].quando.Dia, Amigo[2].quando.Mês, Amigo[2].quando.Ano);
if (Amigo[i].quando.mês[0] = = ‘\0’) ...;
gets((*Ptr_aniversario).Nome); ou gets(Ptr_aniversario->Nome);
scanf(“%d”, &Ptr_aniversario->quando.Dia);
Exemplo:
struct Data
{int Dia;
char Mes[12];
int Ano;
};
struct Aniversario
{char Nome[101];
struct Data quando;
} v = {“Pedro”, {25,”Dezembro”,2000}};
ou
struct Aniversario v = {“Pedro”, {25,”Dezembro”,2000}};
struct Aniversario var = {“Maria”, {1,”Janeiro”,}};
struct Data vect_data[] = {{25, ”Dezembro”, 2000}, {1, ”Abril”, 1999}};
struct Data vect_data[2] = {{25, ”Dezembro”, 2000}, {1, ”Abril”, 1999}};
DEI ESTG/IPLeiria 2
Programação Cap. 6
ou declaração equivalente:
FUNC administrativo, financeiro;
main()
{...}
f()
{...}
DEI ESTG/IPLeiria 3
Programação Cap. 6
#include <stdio.h>
#include <conio.h>
main ()
{
PESSOA p[2]={{"Zé",21,1000.00,{2,10,1982}},
{"Maria",22,1500.00,{25,12,1981}}};
Mostrar(p[0]);
puts("");
Mostrar(p[1]);
puts("");
Ler(&p[1]);
puts("");
Mostrar_tudo(p);
puts("");
getch();
}
DEI ESTG/IPLeiria 4
Programação Cap. 6
Neste exemplo houve uma passagem por referência do vector p, nomeadamente da estrutura p[1]!
Nota: typedef PESSOA p[2]; faz com que p seja um tipo de vector de 2 estruturas struct pessoa.
Exemplo:
struct Data {
int Dia;
char *mes;
int ano;
}dat1,dat2;
dat1.mes=”Abril”;
struct pessoa {
char nome [61];
int ano_nasc;
};
struct pessoa *p
ou com typedef:
typedef struct pessoa *Apont;
Apont p;
Inicialização do apontador:
struct pessoa homem;
p = &homen;
ou
p=(Apont)malloc(sizeof(struct pessoa)); p=(struct pessoa *)malloc(sizeof(struct pessoa));
Exemplo:
struct pessoa {
char nome[61];
struct pessoa *seguinte;
};
ou
DEI ESTG/IPLeiria 5
Programação Cap. 6
typedef struct pessoa *Apont_p; Nota: utilização correcta da estrutura antes da sua definição
struct pessoa {
char nome[61];
Apont_p seguinte;
};
<Nome_enum> é opcional.
<Nome_const> nome da constante que pode ser inicializado com o valor inteiro <valor>. O 1º <valor> é
igual a zero se for omitido a sua inicialização e os valores seguintes serão valores unitários crescentes.
Fields
Um field é uma estrutura com membros compostos com uma quantidade específica de bits. Os tipos field
são utilizados quando a memória é escassa!
Exemplo:
struct {
unsigned int a : 1;
unsigned int b : 3;
} var;
Unions
Exemplo:
union valor {
int x;
double y;
char z;
} var;
A variável var só tem o tamanho de um double, por isso, é necessário saber previamente qual o tipo de
dados que será armazenado. A solução pode ser como no exemplo seguinte:
struct Valor {
char tipo;
union valor {
int x;
double y;
char z;
};
} var;
DEI ESTG/IPLeiria 6
Programação Cap. 7
Cap. 7 – Ficheiros
7.1 Definição
Os ficheiros são estruturas de dados próprias para armazenar dados em memória secundária, por exemplo,
em disco ou disquete.
Nota: Estes “streams” são processados como se fossem ficheiros e podem ser Binários (sem “\n”) ou de
Texto (com linhas “\n”).
E/s formatada:
fscanf
fprintf
E/S carácter/”string”:
getc
fgetc
fgets
putc
fputc
fputs
E/S bloco de dados:
fread
fwrite
Manipulaçãode erros:
clearerr
feof
ferror
Acesso:
fopen
freopen
fclose
fflush
setbuf
setvbuf
Posicionamento:
fgetpos
fsetpos
fseek
ftell
rewind
A estrutura FILE * é utilizada para declarar um apontador de um ficheiro. A função FILE *fopen(const
char *nome_ficheiro, const char *modo_ficheiro) é utilizada para abrir um ficheiro com nome
nome_ficheiro e modo de abertura modo_ficheiro. Este tipo de dados FILE e esta função fopen estão em
<stdio.h>.
DEI ESTG/IPLeiria 1
Programação Cap. 7
Exemplo:
FILE *fptr;
fptr = fopen(“a:\\Dados.dat”, “a+b”);
a:\\Dados.dat é o nome do ficheiro e “a+b” é o modo de abertura em formato binário para leitura
e escrita a partir do fim do ficheiro.
Modos de abertura:
“r” - read (Abertura do ficheiro para Leitura);
“w” - write (Abertura do ficheiro para Escrita);
“a” – append (Abertura do ficheiro para Acrescento);
“r+”, “w+”, “a+” – Abertura do ficheiro para Leitura e Escrita. ;
Por predefinição, os ficheiros são do tipo texto. Para ter um tipo binário, basta acrescentar um b. Por
exemplo: “rb”, “wb”, “ab”, “r+b” ou “rb+”, “w+b” ou “wb+”, “a+b” ou “ab+”.
Nota: Se a função fopen conseguir abrir o ficheiro com sucesso, cria em memória uma estrutura (do tipo
FILE) que representa toda a informação necessária relativa ao ficheiro que estiver a processar,
devolvendo o endereço em que essa estrutura foi criada. Caso não tenha conseguido abrir o ficheiro,
devolve o valor NULL, isto é o endereço zero de memória. Ou seja, devolve NULL quando:
- nome de ficheiro inválido;
- tenta abrir um ficheiro ainda não fechado;
- tenta abrir um ficheiro num local inexistente;
- tenta abrir um ficheiro inexistente em modo r.
Fecho de um ficheiro:
Após se ter realizado o processamento sobre um ficheiro, é necessário fechá-lo. A operação de fecho de
um ficheiro é realizada pela função fclose:
Esta função retorna 0 em caso de sucesso e –1 (EOF) em caso de erro. A função desaloca a respectiva
estrutura FILE e fecha o ficheiro apontado por fp. Quando um ficheiro é fechado, o conteúdo do “buffer”
é escrito no ficheiro.
#include <stdio.h>
main()
{
FILE *fp;
char nome[13];
DEI ESTG/IPLeiria 2
Programação Cap. 7
scanf(“%s”,nome);
if ((fp = fopen(nome, “r”)) != NULL) {
printf(“O ficheiro %s já existe!”, nome);
fclose(fp);
}
else
printf(“O ficheiro %s não existe!”, nome);
}
Notas: - Após fechar um ficheiro, o apontador fp pode ser reutilizado para outros fins!
- Embora os ficheiros sejam automaticamente fechados quando uma aplicação termina, é bom
hábito dos programadores efectuarem eles mesmo o fecho dos ficheiros.
- É possível fechar todos os ficheiros abertos (exepto stdin, stdout, stderr, stdprn e stdaux)
usando a função fcloseall().
ptr: - Apontador para void (qualquer tipo) que contém o endereço de memória daquilo que
pretendemos guardar em ficheiro.
size: - Tamanho em Bytes de cada um dos elementos que pretendemos escrever.
n: - Quantidade de elementos que pretendemos escrever. O valor n será devolvido pela
função fwrite em caso de sucesso.
fich: - Indica o ficheiro onde os dados serão colocados. É o parâmetro devolvido por fopen().
Exemplo:
#include <stdio.h>
#define MAX 5
#define NOME_FICH "a:\\dados.dat"
main()
{
FILE *fp;
int i,v[MAX];
for (i=0; i<MAX;i++)
{
printf("Introduzir o %d-esimo elemento: ", i+1);
scanf("%d",&v[i]);
}
if ((fp=fopen(NOME_FICH,"wb"))==NULL)
{
printf("impossível criar o ficheiro %s\n",NOME_FICH);
}
else
{
if (fwrite(v,sizeof(int),MAX,fp)!=MAX)
printf("Não foram escritos todos os elementos!\n");
fclose(fp);
}
}
Nota: é possível escrever o bloco de dados de uma só vez com fwrite(v ,1, sizeof(int)*MAX, fp); ou
elemento a elemento com o seguinte código for (i=0;i<MAX;i++) fwrite(&v[i] ,sizeof(int),1 ,fp);.
DEI ESTG/IPLeiria 3
Programação Cap. 7
ptr: - Apontador para void (qualquer tipo) que contém o endereço de memória onde
queremos colocar os dados que iremos ler a partir do ficheiro.
size: - Tamanho em Bytes de cada um dos elementos que pretendemos ler
n: - Quantidade de elementos que pretendemos ler. O valor n será devolvido pela função
fread em caso de sucesso.
fich: - Indica o ficheiro de onde os dados irão ser lidos. É o parâmetro devolvido por fopen().
Exemplo:
#include <stdio.h>
#include <conio.h>
#define MAX 5
#define NOME_FICH "a:\\dados.dat"
main()
{
FILE *fp;
int i, n, v[MAX];
if ((fp=fopen(NOME_FICH,"rb"))==NULL)
{
printf("impossível abrir o ficheiro %s\n",NOME_FICH);
}
else
{
n=fread(v,sizeof(int),MAX,fp);
if (n!=MAX)
printf("Foram lidos apenas %d elementos!\n",n);
fclose(fp);
}
getch();
}
Nota: é possível ler o bloco de dados de um só vez com fread(v ,1 ,sizeof(int)*MAX ,fp); ou elemento a
elemento com o seguinte código for (i=0;i<MAX;i++) fread(&v[i] ,sizeof(int),1 ,fp); ou com
i=0;while(fread(&v[i] ,sizeof(int),1 ,fp))i++;
A função feof só detecta uma situação de End-of-File depois de ter sido realizada uma operação sobre o
ficheiro que a provoque. A função feof sobre um ficheiro vazio acabado de abrir devolve falso.
#include <stdio.h>
#include <conio.h>
#define NOME_FICH "a:\\dados.dat"
DEI ESTG/IPLeiria 4
Programação Cap. 7
void main(void)
{
FILE *fptr;
aluno_t dados[2] = {{"Maria",5675,23,12,2003,informatico},
{"Pedro",1176,20,2,2003,matematico}};
aluno_t al;
fptr = fopen(NOME_FICH,"wb");
if (fptr!=NULL)
{
if (fwrite(dados,sizeof(aluno_t),2,fptr)!=2)
printf("Erro de escrita");
fclose(fptr);
}
else
printf("Erro de abertura para escrita");
fptr=fopen(NOME_FICH,"rb");
if (fptr!=NULL)
{
while (fread(&al,sizeof(aluno_t),1,fptr)==1)
{
printf("Nome: %s Número: %ld ", al.nome, al.numero);
printf("Data de Nasc. %d/%d/%d curso:",al.inscricao.dia,al.inscricao.mes,al.inscricao.ano);
switch (al.curso) {
case 0 : printf("informatico\n");break;
case 1 : printf("electrotecnico\n");break;
case 2 : printf("matematico\n");
}
}
if (!feof(fptr))
printf("Erro de leitura!");
fclose(fptr);
}
else
printf("Erro de abertura para leitura");
getch();
}
Leitura de um caracter a partir de fptr. Em caso de erro ou fim de ficheiro a função devolve EOF (-1).
Caso contrário devolve o caracter apontado por fptr. O apontador fptr avança para o elemento seguinte
após efectuar a leitura.
Exemplo:
DEI ESTG/IPLeiria 5
Programação Cap. 7
int conta_digito(void)
{
FILE *fptr;
int ch, conta=0;
fptr=fopen("c:\\lixo2.txt","r");
if(fptr!=NULL)
{
while ((ch=fgetc(fptr))!=EOF)
if(isdigit(ch))
conta++;
//verificar se está no fim do ficheiro. Se não ocorreu um Erro!
if (!feof(fptr))
printf("ERRO de Leitura");
fclose(fptr);
return conta;
}
else
return -1;
}
Escrita de um caracter ch no ficheiro apontado por fptr. Em caso de erro a função devolve EOF (-1). Caso
contrário devolve o caracter escrito. O apontador fptr avança para o elemento seguinte após efectuar a
escrita.
Exemplo:
#include <stdio.h>
#include <conio.h>
void escrever_ficheiro(void);
void copia_ficheiro(void);
void main(void)
{
escrever_ficheiro();
copia_ficheiro();
}
void escrever_ficheiro(void)
{
FILE *fptr;
char str[101];
int i=0;
fptr=fopen("c:\\lixo1.txt","w");
if(fptr==NULL)
printf("Erro na abertuta do Ficheiro para escrita!");
else
{
gets(str);
while (str[i]!='\0')
{
fputc(str[i],fptr);
i++;
}
DEI ESTG/IPLeiria 6
Programação Cap. 7
fputc('\0',fptr);
}
fclose(fptr);
}
void copia_ficheiro(void)
{
FILE *fptr1, *fptr2;
char ch;
fptr1=fopen("c:\\lixo1.txt","r");
fptr2=fopen("c:\\lixo2.txt","w");
if(fptr1==NULL)
printf("Erro na abertuta do Ficheiro para leitura!");
else if (fptr2==NULL)
printf("Erro na abertuta do Ficheiro para escrita!");
else
{
while ((ch=fgetc(fptr1))!=EOF)
if(fputc(ch,fptr2)==EOF)
{
printf("Erro de escrita\n");
break;
}
fclose(fptr1);
fclose(fptr2);
}
}
A função fgets efectua a leitura por linha de uma cadeia de n caracteres (incluído ‘\n’) de um ficheiro
apontado por fptr para uma variável linha parando quando se verificar uma das seguintes condições:
- encontrou o caracter fim de linha (‘\n’);
- encontrou o caracter fim de ficheiro (EOF);
- leu n –1 caracteres;
O valor ‘\0’ é colocado automaticamente no fim da linha. Em caso de erro devolve NULL.
Exemplo:
fptr=fopen(nome_fich,”r”);
if (fptr != NULL)
{
while (fgets(buffer, 100, fptr) != NULL)
{
printf(“Linha %d: %s\n”, linha, buffer);
linha++;
}
DEI ESTG/IPLeiria 7
Programação Cap. 7
if (!feof(fptr))
printf(“Erro de Leitura”);
fclose(fptr);
}
else
printf(“O ficheiro não existe”);
}
A função escreve a cadeia de caracteres linha, a qual necessita conter o carácter ‘\n’, num ficheiro
apontado por fptr. O valor retornado é a quantidade de caracteres escritos ou, em caso de erro, EOF.
Exemplo:
/*Função que vai acrescentando num ficheiro o que o utilizador vai introduzindo. A função termina após
a introdução da palavra “fim”*/
void teclado_ficheiro(char *nome_fich)
{
FILE *fptr;
char buffer[100];
int len;
A função fscanf efectua a leitura formatada a partir de um ficheiro apontado por fich. Se chegar ao fim
devolve EOF. Caso contrário, devolve o número de campos lidos correctamente. Se esse número de
campos lidos for inferior ao esperado então, o formato do ficheiro está incorrecto.
Exemplo:
Maria 24 1.80
Pedro 25 1.82
Catarina 20 1.71
DEI ESTG/IPLeiria 8
Programação Cap. 7
fptr = fopen(nome_fich,”r”);
if (fptr != NULL)
{
numero_fichas = 0;
soma = 0;
while (fscanf(fptr, “%s %d %f”, nome, &idade, &altura) = =3)
{
soma += idade;
numero_fichas++;
printf(“Ficha %d: Nome = %s Idade = %d Altura = %f\n”, numero_fichas,
nome, idade, altura);
}
if (!feof(fptr))
printf(“Erro de Leitura. Formato do ficheiro incorrecto\n”);
else if (numero_fichas>0)
printf(“Media das idades: %f\n”, soma/numero_fichas);
fclose (fptr);
}
else
printf(“O ficheiro nao existe!”);
}
A função fprintf efectua a escrita formatada a partir de um ficheiro apontado por fich. Se chegar ao fim
devolve EOF. Caso contrário, devolve o número de bytes escritos correctamente.
Exemplo:
void main(void)
{
FILE *fptr;
aluno_t dados[2] = {{“Maria”,21},{“Pedro”,24}};
int i;
fptr = fopen(“Dados.txt”,”w”);
if (fptr != NULL)
{
for (i=0; i<2; i++)
if (fprintf(fptr, “%s %ld\n”, dados[i].nome, dados[i].numero) = = EOF)
{
printf(“Erro de escrita\n”);
break;
DEI ESTG/IPLeiria 9
Programação Cap. 7
}
flcose(fptr);
}
else
printf(“Erro ao abrir o ficheiro\n”);
}
DEI ESTG/IPLeiria 10