A maior rede de estudos do Brasil

Grátis
275 pág.
Apostila C

Pré-visualização | Página 42 de 45

na ABERTURA do arqu ivo \n ’ ’ ) ;
12 system ( ‘ ‘ pause ’ ’ ) ;
13 e x i t ( 1 ) ;
14 }
15 fscan f ( arq , ‘ ‘% s%s ’ ’ , tex to , nome) ;
16 p r i n t f ( ‘ ‘% s %s\n ’ ’ , tex to , nome) ;
17 fscan f ( arq , ‘ ‘% s %d ’ ’ , tex to ,& i ) ;
18 p r i n t f ( ‘ ‘% s %d\n ’ ’ , tex to , i ) ;
19 f scan f ( arq , ‘ ‘% s%f ’ ’ , tex to ,&a ) ;
20 p r i n t f ( ‘ ‘% s %f \n ’ ’ , tex to , a ) ;
21
22 f c l o s e ( arq ) ;
23 system ( ‘ ‘ pause ’ ’ ) ;
24 return 0;
25 }
Note, nesse exemplo, que foi preciso ler, em todos os comando fscanf(),
o texto que acompanha os dados gravados no arquivo do exemplo do co-
mando fprintf().
263
A u´nica diferenc¸a dos proto´tipos de fprintf() e fscanf() para
os proto´tipos de printf() e scanf(), respectivamente, sa˜o a
especificac¸a˜o do arquivo destino atrave´s do ponteiro FILE.
Embora as func¸o˜es fprintf() e fscanf() sejam mais fa´ceis de escrever e ler
dados em arquivos, nem sempre elas sa˜o as escolhas mais apropriadas.
Tome como exemplo a func¸a˜o fprint(): os dados sa˜o gravados exatamente
como seriam impressos na tela e podem ser modificados por um editor de
textos simples como o Bloco de Notas. No entanto, para que isso ocorra,
os dados sa˜o gravados como caracteres de 8 bits utilizando a tabela ASCII.
Ou seja, durante a gravac¸a˜o dos dados existe uma etapa de “conversa˜o”
dos dados. Essa “conversa˜o” dos dados faz com que os arquivos sejam
maiores. Ale´m disso, suas operac¸o˜es de escrita e leitura consomem mais
tempo.
Se a intenc¸a˜o do programador e´ velocidade ou tamanho
do arquivo, deve-se utilizar as func¸o˜es fwrite() e fread() ao
inve´s de fprintf() e fscanf(), respectivamente.
O exemplo abaixo apresenta como uma matriz pode ser gravada dentro de
um arquivo e seus dados podem ser posteriormente lidos e somados:
264
Exemplo: gravando e lendo uma matriz
Gravando Lendo
1 #include <s t d i o . h>
2 #include <s t d l i b . h>
3 i n t main ( ) {
4 FILE ∗arq ;
5 arq = fopen ( ‘ ‘ ma t r i z
. t x t ’ ’ , ‘ ‘w ’ ’ ) ;
6 i f ( arq == NULL) {
7 p r i n t f ( ‘ ‘ Erro\n ’
’ ) ;
8 system ( ‘ ‘ pause ’ ’
) ;
9 e x i t ( 1 ) ;
10 }
11 i n t mat [ 2 ] [ 2 ] =
{{1 ,2} ,{3 ,4}} ;
12 i n t i , j ;
13 for ( i = 0 ; i < 2; i
++)
14 for ( j = 0 ; j <
2; j ++)
15 f p r i n t f ( arq
, ‘ ‘%d\n ’
’ , mat [ i
] [ j ] ) ;
16 f c l o s e ( arq ) ;
17 system ( ‘ ‘ pause ’ ’ ) ;
18 return 0;
19 }
1 #include <s t d i o . h>
2 #include <s t d l i b . h>
3 i n t main ( ) {
4 FILE ∗arq ;
5 arq = fopen ( ‘ ‘ mat r i z
. t x t ’ ’ , ‘ ‘ r ’ ’ ) ;
6 i f ( arq == NULL) {
7 p r i n t f ( ‘ ‘ Erro\n ’
’ ) ;
8 system ( ‘ ‘ pause ’ ’
) ;
9 e x i t ( 1 ) ;
10 }
11 i n t i , j , v , soma=0;
12 while ( ! f e o f ( arq ) ) {
13 fscan f ( arq , ‘ ‘%d ’
’ ,&v ) ;
14 soma += v ;
15 }
16 p r i n t f ( ‘ ‘Soma = %d\n
’ ’ ,soma) ;
17 f c l o s e ( arq ) ;
18 system ( ‘ ‘ pause ’ ’ ) ;
19 return 0;
20 }
11.6 MOVENDO-SE DENTRO DO ARQUIVO
De modo geral, o acesso a um arquivo e´ quase sempre feito de modo
sequ¨encial. Pore´m, a linguagem C permite realizar operac¸o˜es de leitura e
escrita randoˆmica. Para isso, usa-se a func¸a˜o fseek(), cujo proto´tipo e´:
int fseek(FILE *fp, long numbytes, int origem)
Basicamente, a func¸a˜o fseek() move a posic¸a˜o atual de lei-
tura ou escrita no arquivo para um byte especı´fico, a partir
de um ponto especificado.
A func¸a˜o fseek() recebe 3 paraˆmetros de entrada
265
• fp: o ponteiro para o arquivo que se deseja trabalhar;
• numbytes: e´ o total de bytes a partir de origem a ser pulado;
• origem: determina a partir de onde os numbytes de movimentac¸a˜o
sera˜o contados.
A func¸a˜o fseek() e retorna um valor inteiro igual a ZERO quando a movimentac¸a˜o
dentro do arquivo for bem sucedida. Um valor de retorno diferente de zero
significa que houve um erro durante a movimentac¸a˜o.
Os valores possı´veis para o paraˆmetro origem sa˜o definidos por constante
na biblioteca stdio.h e sa˜o:
ConstanteValor Significado
SEEK SET0 Inı´cio do arquivo
SEEK CUR0 Ponto atual no arquivo
SEEK END0 Fim do arquivo
Portanto, para movermos numbytes a partir do inı´cio do arquivo, a origem
deve ser SEEK SET. Se quisermos mover a partir da posic¸a˜o atual em que
estamos no arquivo, devemos usar a constante SEEK CUR. E, por fim,
se quisermos mover a partir do final do arquivo, a constante SEEK END
devera´ ser usada.
Exemplo: usando a func¸a˜o fseek()
1 #include <s t d i o . h>
2 #include <s t d l i b . h>
3 i n t main ( ) {
4 FILE ∗arq ;
5 arq = fopen ( ‘ ‘ ArqGrav . t x t ’ ’ , ‘ ‘w ’ ’ ) ;
6 i f ( arq == NULL) {
7 p r i n t f ( ‘ ‘ Problemas na CRAICAO do arqu ivo \n ’ ’ ) ;
8 system ( ‘ ‘ pause ’ ’ ) ;
9 e x i t ( 1 ) ;
10 }
11 fpu t s ( ‘ ‘1234567890 ’ ’ , arq ) ;
12 fseek ( arq ,5 ,SEEK SET) ;
13 fpu t s ( ‘ ‘ abcde ’ ’ , arq ) ;
14 f c l o s e ( arq ) ;
15
16 system ( ‘ ‘ pause ’ ’ ) ;
17 return 0;
18 }
266
No exemplo anterior, o primeiro comando fputs() (linha 10) e´ utilizado para
escrever uma sequeˆncia de 10 dı´gitos em um arquivo. Em seguida, o
ponteiro do arquivo e´ movido em 5 posic¸o˜es a partir do seu inı´cio (linha
11). Isso significa que os dados escritos pelo segundo comando fputs()
(linha 12) sera˜o escritos a partir do 6 byte do arquivo, sobreescrevendo o
que ja´ havia sido escrito.
O valor do paraˆmetro numbytes pode ser negativo depen-
dendo do tipo de movimentac¸a˜o que formos realizar.
Por exemplo, se quisermos se mover no arquivo a parir do ponto atual
(SEEK CUR) ou do seu final (SEEK END), um valor negativo de bytes
e´ possı´vel. Nesse caso, estariamos voltando dentro do arquivo a partir
daquele ponto.
A linguagem C tambe´m permite que se volte para o comec¸o
do arquivo. Para tanto, usa-se a func¸a˜o rewind().
Outra opc¸a˜o de movimentac¸a˜o dentro arquivo e´ simplesmente retornar
para o seu inı´cio. Para tanto, usa-se a func¸a˜o rewind(), cujo proto´tipo
e´:
void rewind(FILE *fp)
A func¸a˜o rewind() recebe como paraˆmetro de entrada apenas o ponteiro
para o arquivo que se deseja retornar para o seu inı´cio.
11.7 EXCLUINDO UM ARQUIVO
Ale´m de permitir manipular arquivos, a linguagem C tambe´m permite exclui-
los do disco rı´gido. Isso pode ser feito facilmente utilizando a func¸a˜o re-
move(), cujo proto´tipo e´:
int remove(char *nome do arquivo)
Diferente das func¸o˜es vistas ate´ aqui, a func¸a˜o remove() recebe como
paraˆmetro de entrada o caminho e nome do arquivo a ser excluı´do do
267
disco rı´gido, e na˜o um ponteiro para FILE. Como resultado, essa func¸a˜o
retorna um valor inteiro igual a ZERO quando houver sucesso na exclusa˜o
do arquivo. Um valor de retorno diferente de zero significa que houve um
erro durante a sua exclusa˜o.
No paraˆmetro nome do arquivo pode-se trabalhar com
caminhos absolutos ou relativos.
Abaixo, tem-se um exemplo de um programa que utiliza a func¸a˜o remove():
Exemplo: usando a func¸a˜o remove()
1 #include <s t d i o . h>
2 #include <s t d l i b . h>
3 i n t main ( ) {
4 i n t s ta tus ;
5 s ta tus = remove ( ‘ ‘ ArqGrav . t x t ’ ’ ) ;
6 i f ( s ta tus != 0){
7 p r i n t f ( ‘ ‘ Erro na remocao do arqu ivo .\n ’ ’ ) ;
8 system ( ‘ ‘ pause ’ ’ ) ;
9 e x i t ( 1 ) ;
10 }else
11 p r i n t f ( ‘ ‘ Arquivo removido com sucesso .\n ’ ’ ) ;
12
13 system ( ‘ ‘ pause ’ ’ ) ;
14 return 0;
15 }
11.8 ERRO AO ACESSAR UM ARQUIVO
Ao se trabalhar com arquivos, diversos tipos de erros podem ocorrer: um
comando de leitura pode falhar, pode na˜o haver espac¸o suficiente em disco
para gravar o arquivo, etc. Para determinar se uma operac¸a˜o realizada com
o arquivo produziu algum erro existe a func¸a˜o ferror(), cujo proto´tipo e´:
int ferror(FILE *fp)
Basicamente, a func¸a˜o ferror() recebe como paraˆmetro o ponteiro fp que
determina o arquivo que se quer verificar. A func¸a˜o verifica se o indicador
de erro associado ao arquivo esta´ marcado, e retorna um valor igual a
zero se nenhum erro ocorreu. Do contra´rio, a func¸a˜o retorna um nu´mero
diferente de zero.
268
Como cada operac¸a˜o modifica a condic¸a˜o de erro do ar-
quivo, a func¸a˜o ferror() deve ser chamada logo apo´s