MANEJO DE ARCHIVOS EN C.

Anuncio
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
-----------------------------------------------------------------------------------------------------------------------
MANEJO DE ARCHIVOS EN C.
Archivos binarios.
En los archivos de texto teníamos registros formados por una cierta cantidad de caracteres alfanuméricos y finalizados en el par CR-LF (o sea Carriadge Return y Line Feed),
brindando el lenguaje un conjunto de funciones para el manejo cómodo de dichos archivos.
En los archivos binarios el concepto de dato se pierde, pues ahora sólo tenemos un flujo
de bytes hacia y desde un dispositivo de almacenamiento. Ello no quiere decir que no
podamos manejar perfectamente archivos de texto, sólo que con un poco más de trabajo.
Pero se puede.
Para abrir un archivo en forma binaria y para lectura, haremos lo siguiente.
if((Archi=fopen(NombArchi,"rb")==NULL) {
cprintf("No pudo abrir el archivo fuente");
getch( ); return;
}
y para abrirlo en modo escritura:
if((Archi=fopen(NombArchi,"wb")==NULL) {
cprintf("No pudo abrir el archivo fuente");
getch( ); return;
}
Siempre es conveniente chequear si la operación fue exitosa.
También es válido aquí todo lo dicho en el modo texto en cuanto a la actualización de
archivos, salvo que ahora va la letra 'b' y no la 't'. Por ejemplo:
ab
rb+
wb+
etc.
Existen dos funciones claves para el manejo de archivos binarios:
int fread(void *Donde_Guarda, int Tam_Bloque, int NroDeBloques, FILE *stream)
int fwrite(void *Desde_Saca, int Tam_Bloque, int NroDeBloques, FILE *stream)
Si estamos leyendo - fread( ) - el primer parámetro indica la dirección a partir de la cual se
almacenarán los bytes extraídos del archivo. En cambio si estamos escribiendo -fwrite( ) indicará la dirección desde dónde se extraerán los datos a grabar en el archivo.
CLASE DE TEORÍA Nro 6
Página 1 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------El elemento de programa que recibe o emite datos puede ser desde una variable simple
hasta arreglos y estructuras complejas de datos.
Estas dos instrucciones reciben o emiten paquetes de bytes de la siguiente manera:
tamaño de cada bloque de una cantidad de bloques
Lo más cómodo es especificar que el tamaño de bloque sea siempre igual a 1, y el número de bloques la cantidad de bytes que deseamos movilizar. Un ejemplo aclarará bien esta
idea:
const DIM = .....
typedef struct TDatos { ............. };
TDato Datos[DIM];
.
.
.
for(i=0;i<DIM;i++)
fread(&Datos[i],1,sizeof(TDatos),Fuente);
O sea vamos extrayendo sizeof(TDatos) bytes - tamaño del registro - y lo vamos almacenando en cada domicilio del vector de estructuras.
En este caso particular TODOS los registros lógicos poseen la misma extensión en bytes.
Pero no siempre es así. Una gran ventaja de tener todos los registros de igual tamaño, es
que podemos acceder aleatoriamente a cualquiera de ellos ya que en el disco se comportan como un arreglo, disponiendo C de instrucciones precisas para accesar a cualquier
posición remota. Veremos esto más adelante con un ejemplo.
Por el momento veamos cómo trabajar con archivos de texto pero en modo binario.
/* --- TALLER DE LENGUAJES I
2014
Leer archivo de texto con fread.cpp
Este programa lee en forma binaria un archivo de texto.
Para esto es necesario leer byte a byte hasta alcanzar el caracter CR
e ir almacenando en cada domicilio Linea[i] el caracter extraído.
El alcanzar cada CR debe ocurrir varias cosas:
- No incorporar ese caracter a la cadena.
- Leer en vacio un caracter mas (el LF) para dejar listo la prox línea.
- Agregar el finalizador '\0' a la cadena extraída.
Lo mas conveniente es implementar una función de usuario denominada
LeerLinea(FILE *, char *).
CLASE DE TEORÍA Nro 6
Página 2 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------NOTA: La búsqueda de cadenas a extraer finaliza cuando la cantidad de
caracteres leído en un ciclo de lectura es 0 : fread( )==0
Tampoco se considero el caso en que haya TAB intercalados en c/
línea del archivo. Esto es fácil de solucionar.
-------------------------------------------------------------------------------------------------------- */
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
const CR = 13;
const LF = 10;
int LeerLinea( FILE *, char * );
// ----------------------------------------------------------------------------------------void main()
{
FILE *Fuente;
char NombFuente[128] = "D:\\DISCO F\\Leng214\\Buscar medida en pulgadas.cpp";
char Linea[128];
int
i;
clrscr();
if((Fuente=fopen(NombFuente,"rb"))==NULL){
cprintf("NO PUDO ABRIR ARCHIVO FUENTE");
getch(); return;
}
while(LeerLinea(Fuente,Linea))
cprintf("%s\r\n",Linea);
fclose(Fuente);
getch();
}
// ---------------------------------------------------------------------------------------------------------
CLASE DE TEORÍA Nro 6
Página 3 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------int LeerLinea(FILE *Archi,char *Linea)
{
char Car;
int i = 0;
while(fread(&Car,1,1,Archi)) {
if(Car!=CR) Linea[i++]=Car;
else {
fread(&Car,1,1,Archi);
Linea[i]='\0';
return(1);
}
}
return(0);
}
// ------------------------------------------------------------------------------------------------------Aquí estamos leyendo línea a línea el programa fuente "Buscar medida en pulgadas.cpp"
el cual se trata, obviamente, de un archivo de texto. El problema es: ¿qué longitud tendrá
cada registro a extraer?: ¡¡cualquiera!!, no lo sabemos. En un texto cada renglón puede
tener cualquier cantidad de caracteres. Entonces tendremos que implementar nuestra
propia función de usuario que nos permita leer cada línea del archivo. Debemos aclarar
un detalle importante: la función fread( ) retorna la cantidad de bytes leídos en cada proceso de lectura. Esto quiere decir que podríamos utilizar la misma función para detectar
cuándo hemos llegado al final del archivo: en ese momento no se pueden extraer más
caracteres y retorna 0. Ello se refleja en:
while(fread(&Car, 1, 1, Archi))
o sea mientras fread( ) sea distinto de 0.
¿Cómo sabremos cuándo hemos llegado al final de cada línea?: detectando el par CR-LF
while(fread(&Car,1,1,Archi)) {
if(Car!=CR) Linea[i++]=Car;
else {
fread(&Car,1,1,Archi);
Linea[i]='\0';
return(1);
}
}
return(0);
CLASE DE TEORÍA Nro 6
Página 4 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------Aquí dice lo siguiente: si el caracter actual no es un CR, quiere decir que no hemos llegado al final de la línea y debemos, por lo tanto, almacenarlo en la cadena. Ahora bien, en el
caso de haber alcanzado CR, sabemos que a la par existe un LF que no debemos tomar.
Leemos dicho caracter en vacío (sin agregarlo a la cadena), colocamos el finalizador '\0' y
retornamos (con valor 1) al punto de invocación, expresando que pudo extraer exitosamente el registro actual del archivo de texto.
Este proceso se repite hasta alcanzar el último registro.
Ahora vamos a proceder al revés: vamos a partir de datos individuales, vamos a armar
una cadena de texto y por último vamos a grabarla en un archivo de texto.
/* --- TALLER DE LENGUAJES I
2014
La funcion sprintf con archivos binario.cpp
Este programa genera un archivo de texto, pero trabajando con archivos
binarios. Para ello, se conforma la cadena con sprintf( ) -la cual finaliza la línea con '\' y no con el par CR+LF, el cual normalmente es
agregado por fprintf( ). Ello quiere decir que dichos caracteres deberán ser agregados por nosotros a través de la función strcat( ). Una
vez completa de este modo, la cadena es transferida al archivo con la
function fwrite( ).
-------------------------------------------------------------------------------------------------------- */
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
const CR = 13;
const LF = 10;
// -----------------------------------------------------------------------------------------------------------void main()
{
FILE *Destino;
char NombDestino[128] = "D:\\DISCO F\\Leng214\\Archivo para prueba de sprintf.txt";
int
Codigo
= 3518;
char Nombre[30]
= "JOSE JULIAN JUAREZ";
float SupCub
= 324.58;
char Estado[20]
= "INMEJORABLE";
char Linea[128];
int
i;
CLASE DE TEORÍA Nro 6
Página 5 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------clrscr();
if((Destino=fopen(NombDestino,"wb"))==NULL) {
cprintf("NO PUDO CREAR ARCHIVO DESTINO");
getch(); return;
}
sprintf(Linea,"%10d%30s%10.2f%20s",Codigo,Nombre,SupCub,Estado);
strcat(Linea,"\r\n");
for(i=0;i<10;i++) {
fwrite(Linea,1,strlen(Linea),Destino);
cprintf("%s%c",Linea,'!');
}
fclose(Destino);
getch();
}
// ---------------------------------------------------------------------------------------------------------------
Hemos grabado 10 líneas iguales en el archivo.
La función sprintf( ) a diferencia de nuestra conocida printf( ) o cprintf( ) que mostraban
información formateada por pantalla, ésta lo hace hacia una cadena de caracteres. Su
sintaxis es:
sprintf ( char *CadDestino, "... cadena de formatos ...", Variables );
La función sscanf( ).
Si bien no es una función de archivos, está relacionado con ellos cuando el mismo es leído línea a línea y se deben extraer datos (o campos) específicos de ellas. Su sintaxis es
la siguiente:
sscanf(char *Cad, "... cadena de formatos ...", Direcc de variables );
Es similar la función fscanf( ), pero con la diferencia que en lugar de leer con formatos una
línea de archivo, lo hace desde una cadena de caracteres.
Sin embargo existe una diferencia importante: funciona mal cuando la cadena está formada por un número dado de valores (por ejemplo enteros) y los mismos deben ser extraídos con un lazo for. Por ejemplo la siguiente cadena:
128
314
CLASE DE TEORÍA Nro 6
258
614
879
588
Página 6 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------Es obvio que la solución trivial es la siguiente:
sscanf(Cad,"d%d%d%d%d%d%d",&V[0],&V[1],......&V[5]);
y funciona muy bien. Pero....¿qué pasaría si tuviésemos 1024 o más valores en la misma
cadena?¿escribiríamos 1024 veces %d y 1024 veces &V[...] ?. No es práctico: lo ideal
sería leer la cadena con un lazo for. Pero ahí es donde se presentan los problemas.
Veamos por qué:
La función fscanf( ) tienen una particularidad: un puntero de archivo que va incrementándose a medida que leemos el archivo. Ello haría que en un lazo de lectura:
for(i=0;i<6;i++)
fscanf(Archi,"%d",&V[ i ]);
se extraigan sin problemas.
Sin embargo ello mismo mismo aplicado a sscanf( ) no funciona:
for(i=0;i<6;i++)
sscanf(Cad,"%d",&V[ i ]);
LEE SIEMPRE sólo el primer valor almacenado en Cad porque al completar cada ciclo del
lazo for, arranca siempre desde el comienzo de la misma.
Para solucionar es pequeño inconveniente hemos desarrollado el siguiente programa:
/* --- TALLER DE LENGUAJES I
sscanf para un lazo for.cpp
2014
Este programa elimina la limitación de sscanf( ) cuando debe
extraer de una misma línea de texto un conjunto de variables
de una a la vez mediante un lazo for (puesto que siempre vuelve a extraer desde el inicio). La llamaremos sscanf_( char *).
En esta función, i hace de puntero interno a la cadena para
quen en la próxima invocación pueda rastrear el valor numérico
que continua al anterior. Algo similar a lo que hace la función
fscanf( ) con el puntero de archivo.
-------------------------------------------------------------------------------------------------- */
#include <conio.h>
#include <stdlib.h>
#include <string.h>
const DIM = 6;
CLASE DE TEORÍA Nro 6
Página 7 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------int sscanf_ ( char * );
// ---------------------------------------------------------------------------------------------------------void main()
{
char Linea[128] = "128 314 258 614 879 588";
int V[DIM];
int i;
clrscr();
for(i=0;i<DIM;i++)
V[i]=sscanf_(Linea);
for(i=0;i<DIM;i++)
cprintf("%4d",V[i]);
}
// ---------------------------------------------------------------------------------------------------------int sscanf_ (char *Cad)
{
static int i = 0;
int
Aux;
while(Cad[i]==' ') i++;
Aux=atoi(&Cad[i]);
while((Cad[i]!=' ') && (Cad[i]!='\0')) i++;
return(Aux);
}
// ----------------------------------------------------------------------------------------------------------La función sscanf_ sustituirá a la predefinida sscanf( ) del lenguaje, e implica lo siguiente:
generamos con "i" una suerte de puntero interno que se vaya actualizando con cada lectura consecutiva. Para ello la hemos declarado con el prefijo static que tiene la siguiente
particularidad:
Se inicializa UNA SOLA VEZ al ingresar por primera vez a la función.
Se queda CON EL ULTIMO valor que tomó dentro de la función.
Esto produciría que cada vez que se ingresa nuevamente a la función "i" mantiene el valor
que había obtenido durante la invocación anterior.
Lo que hace esta función es "saltear" blancos iniciales o intermedios entre dos cadenas
numéricas y tomar la dirección a partir de la cual se hallan caracteres numéricos. Así por
ejemplo:
CLASE DE TEORÍA Nro 6
Página 8 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------while(Cad[ i ] == ' ') i++; ---> saltea blancos previos al primer caracter numérico.
Aux = atoi ( &Cad[i] );
---> convierte a valor numérico la cadena numérica.
while((Cad[ i ]!=' ') && (Cad[ i ] !='\0')) i++; ---> mueve "i" hasta el próximo blanco.
y como "i" era static, lo encuentra con este valor actualizado al invocar nuevamente.
Ahora vamos a hacer algunas modificaciones al programa anterior para que pueda leer un
archivo de texto (obviamente en forma binaria) y almacenar valores, no en un arreglo, sino
en una matriz de enteros de DIM1 x DIM2 domicilios. He aquí el código fuente;
/* --- TALLER DE LENGUAJES I 2014
Leer matriz desde archivo de texto pero en forma binaria.cpp
Este codigo va leyendo línea a línea (en forma binaria) un archivo de texto y toma en
cuenta que si se topa con un TAB, este sea convertido en 4 espacios en blanco. También
se ha agregado una pequeña modificación en sscanf_( ) que reinicializa el "puntero" de
línea" i", cuando se ha llegado al final de cada cadena.
------------------------------------------------------------------------------------------------------------ */
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
const DIM1 = 10;
const DIM2 = 8;
typedef int TMat[DIM1][DIM2];
int LeerLinea ( FILE *, char * );
int sscanf_
( char *
);
// -------------------------------------------------------------------void main()
{
FILE *Fuente;
char
NombFuente[128] = "D:\\DISCO F\\Leng214\\Matriz como texto.txt";
char
Linea[128];
TMat M;
int
i, j;
clrscr();
CLASE DE TEORÍA Nro 6
Página 9 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------if((Fuente=fopen(NombFuente,"rb"))==NULL) {
cprintf("NO PUDO ABRIR ARCHIVO FUENTE");
getch(); return;
}
for(i=0;i<DIM1;i++) {
LeerLinea(Fuente,Linea);
for(j=0;j<DIM2;j++)
M[i][j]=sscanf_(Linea);
}
for(i=0;i<DIM1;i++) {
for(j=0;j<DIM2;j++) cprintf("%4d",M[i][j]);
cprintf("\r\n");
}
}
// ---------------------------------------------------------------------------------------------------------------int sscanf_(char *Cad)
{
static int i = 0;
int Aux;
while(Cad[i]==' ') i++;
Aux=atoi(&Cad[i]);
while((Cad[i]!=' ') && (Cad[i]!='\0')) i++;
if(Cad[i]=='\0') i=0;
return(Aux);
}
// --------------------------------------------------------------------------------------------------------------int LeerLinea(FILE *Archi,char *Linea)
{
static const CR = 13;
static const TAB = 9;
char Car;
int
i = 0;
int
j;
CLASE DE TEORÍA Nro 6
Página 10 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------while(fread(&Car,1,1,Archi)!=0) {
switch(Car) {
case TAB : for(j=0;j<4;j++) Linea[i++]=' ';
break;
case CR : fread(&Car,1,1,Archi);
Linea[i]='\0';
return(1);
default : Linea[i++]=Car;
}
}
return(0);
}
// -----------------------------------------------------------------------------------------------------------------La función LeerLinea( ) ahora toma en cuenta que los blancos del archivo de texto puedan contener tabuladores. En ese caso reemplaza al mismo por 4 espacios en blanco. El
resto continúa igual: si se topó con un CR "i" se queda allí y en ese lugar se almacena el
finalizador '\0'. Se lee en vació el LF que sigue al CR y se retorna la cadena.
for(i=0;i<DIM1;i++) {
LeerLinea(Fuente,Linea);
for(j=0;j<DIM2;j++)
M[ i ][ j ] = sscanf_(Linea);
}
Para cada valor de "i" se lee una línea de archivo, la cual contiene todas las columnas
necesarias manejadas por "j".
El archivo de texto utilizado fue el siguiente:
877
982
691
113
807
468
766
365
514
229
446
938
911
672
224
594
383
783
267
984
568
609
878
911
101
556
415
287
996
961
CLASE DE TEORÍA Nro 6
973
466
802
637
519
365
986
848
106
160
851
130
991
496
697
742
117
649
416
946
120
923
853
523
603
679
533
438
685
429
755
695
576
944
222
994
440
800
313
283
976
320
684
656
577
138
189
506
162
132
Página 11 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------En archivos binarios existen dos funciones adicionales que pueden ser muy útiles:
putw( ) y getw( ) para escribir y leer, respectivamente, enteros en forma binaria y no de
texto. Debemos recordar que una magnitud entera se almacena (en un formato binario) en
una cierta cantidad de bytes. Por ejemplo en algunos compiladores antiguos como las
versiones de BorlandC para DOS, los enteros se almacenaban en 2 bytes y su rango iba
de -32768 hasta +32767 lo cual equivalía a decir que podíamos disponer de 65536 valores diferentes: la mitad con signo negativo y la otra con signo positivo. En otras versiones
de compiladores como el BCC32, los enteros normales poseen 4 bytes y su rango obviamente es muchísimo mayor. De eso se trata esta dos funciones, de trabajar en ese formato.
/* --- TALLER DE LENGUAJES I 2014
Escribir una lista de enteros con putw.cpp
Este programa genera una lista de enteros en un archivo utilizando la función:
int putw ( int w, FILE *stream );
Esta función no espera ni genera ninguna alineación especial en el archivo.
Exito --> retorna el entero w.
Fallo --> retorna EOF
Posteriormente se realiza una lectura del archivo numérico generado con putw, con la
función complementaria de esta:
int getw( FILE *stream);
Para detectar el final de archivo convienen utilizar la función
feof(FILE *stream)
puesto que EOF tambien puede ser un número válido.
------------------------------------------------------------------------------------------------------------- */
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
CLASE DE TEORÍA Nro 6
Página 12 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------void main( )
{
const TOT_NUM = 128;
FILE
FILE
char
char
int
int
*Destino;
*Fuente;
NombDestino[128] = "D:\\DISCO F\\Leng214\\Lista con putw.dat";
NombFuente [128] = "D:\\DISCO F\\Leng214\\Lista con putw.dat";
NumGen;
i;
clrscr(); randomize();
if((Destino=fopen(NombDestino,"wb"))==NULL) {
cprintf("NO PUDO GENERAR ARCHIVO DESTINO");
getch( ); return;
}
for(i=0;i<TOT_NUM;i++) {
NumGen=100+random(900);
putw(100+random(900),Destino);
}
fclose(Destino);
// ---------------------------------------------------------------------------------------------------------------if((Fuente=fopen(NombFuente,"rb"))==NULL) {
cprintf("NO PUDO ABRIR EL ARCHIVO FUENTE");
getch(); return;
}
while(!feof(Fuente)) {
NumGen = getw(Fuente);
cprintf("%4d",NumGen);
}
fclose(Fuente);
getch( );
}
// ---------------------------------------------------------------------------------------------------------------------
Aquí simplemente hemos creado y rescatado una lista o especie de vector de valores numéricos. Ahora vamos a darle un formato de matriz.
CLASE DE TEORÍA Nro 6
Página 13 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------/* --- TALLER DE LENGUAJES I 2014
Cargar matriz con tabla creada con putw.cpp
Este programa genera una lista de enteros en formato binario utilizando la función putw( ),
con los cuales se piensa posteriormente alimentar una matriz 2D de 12 x 10. Esto quiere
decir que la lista deberá contener 12x10=120 elementos enteros. Una vez creada la lista,
se cierra el archivo y se abre el mismo, pero en modo lectura. La carga de la matriz se
realiza leyendo cada elemento con getw( ) y asignándolo a cada elemento M[ i ][ j ]. Finalmente se muestra por pantalla.
------------------------------------------------------------------------------------------------------------ */
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
const DIM1 = 12;
const DIM2 = 10;
typedef int TMat[DIM1][DIM2];
// -----------------------------------------------------------------------------------------------------------------void main()
{
FILE
FILE
char
char
TMat
int
int
*Destino;
*Fuente;
NombDestino[128] = "D:\\DISCO F\\Leng214\\Lista_putw.dat";
NombFuente [128] = "D:\\DISCO F\\Leng214\\Lista_putw.dat";
M;
NumGen;
i, j;
clrscr();
if((Destino=fopen(NombDestino,"wb"))==NULL) {
cprintf("NO PUDO GENERAR ARCHIVO DESTINO");
getch( ); return;
}
for(i=0;i<DIM1*DIM2;i++) {
NumGen=100+random(900);
putw(NumGen,Destino);
}
fclose(Destino);
// --------------------------------------------------------------CLASE DE TEORÍA Nro 6
Página 14 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------if((Fuente=fopen(NombFuente,"rb"))==NULL) {
cprintf("NO PUDO ABRIR ARCHIVO FUENTE");
getch(); return;
}
for(i=0;i<DIM1;i++) {
for(j=0;j<DIM2;j++) {
M[ i ][ j ] = getw(Fuente);
cprintf("%4d",M[ i ][ j ]);
}
cprintf("\r\n");
}
fclose(Fuente);
getch();
}
En realidad tendríamos un archivo secuencial donde todos los valores numéricos se hallan uno a la par del otro. La lectura también es secuencial, pero no la asignación de estos
valores puesto que los lazos for se encargan de distribuir correctamente las magnitudes
leídas.
Ahora un problema un poco más interesante: convertir un archivo de texto con formato en
un archivo binario con registros de igual longitud.
/* --- TALLER DE LENGUAJES I 2014
Convertir de archivo de texto a binario.cpp
Este programa lee un archivo de texto con formato utilizando la función fscanf( ) y lo convierte en un archivo binario mediante la función fwrite( ). Como elemento intermediario
emplea una estructura (que será el registro lógico) y la irá almacenando para cada registro leído. Es decir, ahora tendremos un nuevo registro lógico (siempre de la misma medida), que será la estructura.
------------------------------------------------------------------------------------------------------------- */
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <alloc.h>
CLASE DE TEORÍA Nro 6
Página 15 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------typedef struct { int
char
float
char
Codigo;
Domicilio[30];
SupCub;
Estado[16];
} TDatos;
// -----------------------------------------------------------------void main()
{
TDatos *Datos;
FILE *Fuente;
FILE *Destino;
char NombFuente [128] = "D:\\DISCO F\\Leng214\\Lista de propiedades.txt";
char NombDestino[128] = "D:\\DISCO F\\Leng214\\Lista de propiedades.bin";
char Blancos1[16];
char Blancos2[13];
clrscr();
if((Datos=(TDatos *)malloc(sizeof(TDatos)))==NULL) {
cprintf("NO SE PUDO RESERVAR MEMORIA DINAMICA");
getch(); return;
}
if((Fuente=fopen(NombFuente,"rt"))==NULL) {
cprintf("NO PUDO ABRIR ARCHIVO FUENTE");
getch(); return;
}
if((Destino=fopen(NombDestino,"wb"))==NULL) {
cprintf("NO PUDO CREAR ARCHIVO DESTINO");
fclose(Fuente);
getch(); return;
}
while(fscanf(Fuente,"%d%[^\A-Z-a-z]%30c%f%[^\A-Z-a-z]%s\n",
&Datos->Codigo,
Blancos1,
Datos->Domicilio,
&Datos->SupCub,
Blancos2,
Datos->Estado )!=EOF) {
cprintf("Codigo
: %d\r\n", Datos->Codigo);
cprintf("Domicilio
: %s\r\n", Datos->Domicilio);
cprintf("SupCubierta : %6.2f\r\n", Datos->SupCub);
cprintf("Estado
: %s\r\n", Datos->Estado);
CLASE DE TEORÍA Nro 6
Página 16 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------fwrite(Datos,1,sizeof(TDatos),Destino);
cprintf("-------------------------------------\r\n");
// if(getch()==27) break;
}
fclose(Fuente); fclose(Destino); getch();
}
Este programa trabaja sobre un archivo ya conocido por nosotros:
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
Av. Alem 2145
258.50
San Lorenzo 3520
185.00
Crisostomo Alvarez 1948 325.50
Lamadrid 4200
225.00
Amador Lucero 75
450.00
Pje Lavalle 2447
250.00
Av. Ernesto Padilla 568
315.00
Italia 2200
272.00
Pje Virrey Vertiz 1235
285.00
Asuncion 1240
180.00
Bolivia 3518
125.00
Lamadrid 2560
100.00
Constitucion 450
480.00
Baltazar Aguirre 385
295.00
Rondeau 628
150.00
Alsina 2320
280.00
Pueyrredon 520
110.00
Colombia 3485
158.00
Guatemala 618
260.00
Pje Zantillan 3125
290.00
Mejico 350
168.00
Chacabuco 325
200.00
Ayacucho 156
350.00
Bolivar 963
215.00
Jujuy 420
380.00
Las Piedras 932
60.00
Lincoln 530
90.00
Gorriti 180
240.00
Agustin Masa 340
218.00
Viamonte 968
114.00
CLASE DE TEORÍA Nro 6
Habitable
Reparaciones
Excelente
Habitable
Excelente
Modificaciones
Excelente
Regular
Excelente
Excelente
Reparaciones
Habitable
Excelente
Reparaciones
Habitable
Excelente
Habitable
Reparaciones
Regular
Excelente
Regular
Reparaciones
Regular
Regular
Excelente
Excelente
Reparaciones
Regular
Excelente
Reparaciones
Página 17 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------El tramo de código:
while(fscanf(Fuente,"%d%[^\A-Z-a-z]%30c%f%[^\A-Z-a-z]%s\n",
&Datos->Codigo,
Blancos1,
Datos->Domicilio,
&Datos->SupCub,
Blancos2,
Datos->Estado )!=EOF) {
utiliza los trucos ya explicados en la clase pasada para poder leer correctamente archivos
de texto con formatos y extrae, o asigna, a variables individuales del tipo adecuado. Estas
variables son, obviamente, cada uno de los miembros de la estructura que constituirá cada registro lógico del archivo binario (todos de la misma longitud).
La instrucción:
fwrite(Datos,1,sizeof(TDatos),Destino);
es la encargada de guardar cada registro en el archivo binario.
Aquí se ve mucho mejor lo que dijimos en un comienzo: tomar como tamaño de bloques 1
byte y guardar la estructura completa: sizeof(TDatos).
Como segunda parte de este programa, mostraremos otro en el cual, ya grabado el archivo binario, procedemos a leerlo aleatoriamente, o sea saltando a registros remotos:
/* --- TALLER DE LENGUAJES I 2014
Leer aleatoriamente un archivo (binario Lista de propiedades_bin).cpp
Este programa lee de manera aleatoria 4 registros de un archivo binario. Para ello utiliza
la función fseek( ) debiendo tener muy en cuenta que los desplazamientos son en CANTIDAD DE BYTES y no solamente en cantidad de registros. Note la sintaxis:
fseek(Fuente,NroReg[ i ]*sizeof(TDatos),SEEK_SET)
donde el punto de referencia elegido es desde el origen:
SEEK_SET --> a partir del origen del archivo.
SEEK_CUR --> a partir de la posición actual del puntero.
SEEK_END --> a partir del final del archivo.
------------------------------------------------------------------------------------------------------------- */
CLASE DE TEORÍA Nro 6
Página 18 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <alloc.h>
typedef struct TDatos {
int Codigo;
char Domicilio[30];
float SupCub;
char Estado[16];
} TDatos;
// --------------------------------------------------------------------------------------------------------------------void main( )
{
TDatos *Datos;
FILE *Fuente;
char
NombFuente[128] = "D:\\DISCO F\\Leng214\\Lista de propiedades.bin";
int
NroReg[4]
= { 3,10,28,0 }; // ... registros a leer aleatoriamente.
int
i;
clrscr( );
if((Datos=(TDatos *)malloc(sizeof(TDatos)))==NULL){
cprintf("NO PUDO RESERVAR MEMORIA DINAMICA");
getch(); return;
}
if((Fuente=fopen(NombFuente,"rb"))==NULL) {
cprintf("NO PUDO ABRIR ARCHIVO FUENTE");
getch(); return;
}
for(i=0;i<4;i++) {
fseek(Fuente,NroReg[i]*sizeof(TDatos),SEEK_SET);
fread(Datos,1,sizeof(TDatos),Fuente);
cprintf("Codigo
: %d\r\n", Datos->Codigo);
cprintf("Domicilio
: %s\r\n", Datos->Domicilio);
cprintf("SupCubierta : %6.2f\r\n", Datos->SupCub);
cprintf("Estado
: %s\r\n", Datos->Estado);
cprintf("---------------------------------------------------------\r\n");
// if(getch()==27) break;
}
CLASE DE TEORÍA Nro 6
Página 19 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------fclose(Fuente); getch();
}
La instrucción:
fseek(Fuente,NroReg[i]*sizeof(TDatos),SEEK_SET);
encargada de posicionar el puntero de archivo en una posición dada, realiza saltos en
cantidades de bytes. Es por eso que si se desea ir al registro 4, en realidad tendríamos
que hacer 4.sizeof(TDatos) de lo contrario sólo aterrizaríamos en el byte nro 4.
En cuanto a la lectura de cada registro:
fread(Datos,1,sizeof(TDatos),Fuente);
debe extraerse el paquete completo equivalente a la estructura: sizeof(TDatos).
Otro ejemplo de aplicación de archivos binarios.
/* --- TALLER DE LENGUAJES I 2014
Archivo binario de números primos.cpp
Este programa genera una tabla de números primos entre 2 y 32000
y los va almacenando en un archivo binario con la función putw( ).
--------------------------------------------------------------------------------------------------------- */
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void main()
{
int Total = 32000;
int i,j;
int EsPrimo;
FILE *Destino;
char NombDestino[128] = "D:\\DISCO F\\Leng214\\Tabla de Primos.bin";
clrscr();
CLASE DE TEORÍA Nro 6
Página 20 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------if((Destino=fopen(NombDestino,"wb"))==NULL) {
cprintf("NO PUDO CREAR ARCHIVO DESTINO");
getch(); return;
}
for(i=2;i<Total;i++) {
EsPrimo=1;
for(j=2;j<=sqrt(i);j++)
if(i%j==0) {
EsPrimo=0;
break;
}
if(EsPrimo) {
cprintf("%20d\r\n",i);
fwrite(&i,1,sizeof(int),Destino);
}
}
fclose(Destino);
cprintf(" ARCHIVO DE PRIMOS GENERADO EXITOSAMENTE...");
getch();
}
Dos modos de determinar la longitud de un archivo.
Vamos a tratar binariamente un archivo del tipo que sea y generado por la aplicación que
sea, a fin de determinar su tamaño en bytes. Existen dos formas: una un tanto artesanal
en la cual se realiza un proceso de lectura con fread( ), que, como sabemos nos devuelve
en cada ciclo el número de bytes extraídos, y simplemente llevando una cuenta de estos
caracteres. La otra: utilizando funciones más específicas como fseek( ) y ftell( ) que nos
ahorra varios pasos. Veamos el programa:
/* --- TALLER DE LENGUAJES I
Tamanio de un archivo.cpp
2014
Este programa determina la longitud en bytes de un archivo de cualquier tipo (binario o de
texto). Lo resuelve de dos maneras distintas: una un tanto artesanal recorriendo el archivo
hasta el final y la otra utilizando instrucciones mas especificas.
--------------------------------------------------------------------------------------------------------------- */
CLASE DE TEORÍA Nro 6
Página 21 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
-----------------------------------------------------------------------------------------------------------------------
#include <conio.h>
#include <stdio.h>
int FileSize ( char * );
int FileSize_ ( char * );
// ---------------------------------------------------------------------------------------------------------------void main( )
{
char NombArchi[128] = "E:\\Leng214\\Tabla de Primos.txt";
clrscr();
cprintf("Tamanio de %s : %d\r\n",NombArchi,FileSize (NombArchi));
cprintf("Tamanio de %s : %d\r\n",NombArchi,FileSize_(NombArchi));
getch( );
}
// -------------------------------------------------------------------------------------------------------------int FileSize(char *NombArchi)
{
FILE *Aux;
char Buff[1024];
int Cuenta = 0;
int Leidos;
if((Aux=fopen(NombArchi,"rb"))==NULL) {
cprintf("NO PUDO ABRIR EL ARCHIVO.");
getch(); return(-1);
}
while((Leidos=fread(Buff,1,sizeof(Buff),Aux))!=0) Cuenta+=Leidos;
fclose(Aux);
return(Cuenta);
}
// -------------------------------------------------------------------------------------------------------------int FileSize_(char *NombArchi)
{
FILE *Archi;
int Tamanio;
if((Archi=fopen(NombArchi,"rb"))==NULL) {
cprintf("NO PUDO ABRIR EL ARCHIVO.");
getch(); return(-1);
}
CLASE DE TEORÍA Nro 6
Página 22 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------fseek(Archi,0,SEEK_END);
Tamanio=ftell(Archi);
fclose(Archi);
return(Tamanio);
}
En la primer función:
while((Leidos=fread(Buff,1,sizeof(Buff),Aux))!=0) Cuenta+=Leidos;
los bytes leídos son acumulados en Cuenta, la cual, al final, contendrá un equivalente del
total de bytes del archivo.
La segunda función de usuario hace lo siguiente:
fseek(Archi,0,SEEK_END);
Tamanio=ftell(Archi);
envía el puntero de archivo al final del mismo mediante seek( ) y luego solicita que indique la posición de dicho puntero: ftell( ).
fseek( ) dice: vaya al final del archivo (SEEK_END) y tome un desplazamiento 0 mientras
que ftell( ) retorna a cuántos bytes del origen se halla este apuntador.
NOTA: Debemos hacer notar un detalle: si hacemos click derecho sobre el archivo evaluado:
CLASE DE TEORÍA Nro 6
Página 23 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
-----------------------------------------------------------------------------------------------------------------------
se visualizarán dos tamaños:
El tamaño real.
El tamaño en disco.
Lo que nosotros hemos determinado con nuestro programa es el tamaño real. Como el
sistema operativo posee un paquete mínimo de acceso en disco que es el "cluster", cuya
extensión en bytes se establece en el momento de particionar y formatear el disco, 4096
en nuestro caso, al guardar un archivo de 5 bytes, en Propiedades leeríamos:
Tamaño : 5
Tamaño en disco: 4096
o sea que en archivos pequeños estamos desperdiciando cierta cantidad de bytes.
CLASE DE TEORÍA Nro 6
Página 24 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
-----------------------------------------------------------------------------------------------------------------------
Implementando un replicador de archivos.
Otra aplicación útil y sencilla de implementar con archivos binarios es un replicador o duplicador de archivos. Simplemente se trata de un proceso sistemático de lectura/escritura
hasta finalizar el archivo en cuestión.
/* --- TALELR DE LENGUAJES I 2014 - Replicador.cpp
Este programa replica (copia) un archivo en la misma o en alguna otra
carpeta y lo mismo con el nombre.
------------------------------------------------------------------------------------------------------------------ */
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
// ------------------------------------------------------------------------------------------------------------------void main()
{
FILE *Fuente;
FILE *Destino;
char NombFuente [128] = "E:\\JOE DOLAN\\Crazy woman - Joe Dolan.wav";
char NombDestino[128] = "G:\\Crazy woman - Joe Dolan.wav";
char BuffFuente [32768];
int Leidos;
int i;
if((Fuente=fopen(NombFuente,"rb"))==NULL) {
cprintf("ARCHIVO FUENTE NO ENCONTRADO\r\n");
getch(); return;
}
if((Destino=fopen(NombDestino,"wb"))==NULL) {
cprintf("ARCHIVO DESTINO NO ENCONTRADO\r\n");
getch(); fclose(Fuente); return;
}
while((Leidos=fread(BuffFuente,1,32768,Fuente))!=0)
fwrite(BuffFuente,1,Leidos,Destino);
CLASE DE TEORÍA Nro 6
Página 25 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------fclose(Fuente); fclose(Destino);
cprintf("ARCHIVO REPLICADO\r\n");
getch();
}
Las líneas:
while((Leidos=fread(BuffFuente,1,32768,Fuente))!=0)
fwrite(BuffFuente,1,Leidos,Destino);
realizan una operación simétrica: la misma cantidad de bytes que lee fread( ) es la que
copia o replica fwrite( ).
Comparador de archivos.
/* --- TALLER DE LENGUAJES I 2014
Comparador de archivos 2.cpp
Este programa compara dos archivos de texto: "Texto para lectura.txt" y "Texto para lectura con diferencia.txt", practicamente iguaes, salvo una letra que hemos escrito mal a proposito: una c por una s.
Primero compara las longitudes: si son diferentes asume que los archivos tambien lo son.
Si las longitudes son iguales comienza a leer bloques de tamaño ientico y compara byte a
byte. Mientras tanto va llevando una cuenta del numero de caracteres comparados a fin
de poder establecer el valor exacto a partir del cual encuentra la primera diferencia.
------------------------------------------------------------------- */
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
// --------------------------------------------------------------------------------------void main()
{
FILE *Fuente1;
FILE *Fuente2;
char NombFuente1[128] = "D:\\DISCO F\\Leng214\\Texto para lectura.txt";
CLASE DE TEORÍA Nro 6
Página 26 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------char
rencia.txt";
char
char
int
int
int
int
NombFuente2[128] = "D:\\DISCO F\\Leng214\\Texto para lectura con difeBuff1[128];
Buff2[128];
Tam1,Tam2;
Leidos;
ComDeDiff = 0;
i;
if((Fuente1=fopen(NombFuente1,"rb"))==NULL) {
cprintf("ARCHIVO FUENTE 1 NO ENCONTRADO\r\n");
getch(); return;
}
if((Fuente2=fopen(NombFuente2,"rb"))==NULL) {
cprintf("ARCHIVO FUENTE 2 NO ENCONTRADO\r\n");
getch(); fclose(Fuente1); return;
}
fseek(Fuente1,0,SEEK_END); Tam1=ftell(Fuente1);
fseek(Fuente2,0,SEEK_END); Tam2=ftell(Fuente2);
fseek(Fuente1,0,SEEK_SET); // ... reposiciona al comienzo.
fseek(Fuente2,0,SEEK_SET); // ... reposiciona al comienzo.
if(Tam1!=Tam2) {
cprintf("POSEEN DISTINTOS TAMANIOS");
getch(); fclose(Fuente1); fclose(Fuente2);
return;
}
while((Leidos=fread(Buff1,1,128,Fuente1))!=0) {
fread(Buff2,1,128,Fuente2);
for(i=0;i<Leidos;i++) {
if(Buff1[i]!=Buff2[i]) {
ComDeDiff+=i;
cprintf("Los archivos son diferentes.\r\n");
cprintf("Las diff se dieron a partir del byte : %d\r\n",ComDeDiff);
cprintf("Caracteres diferentes: %c %c\r\n",Buff1[i],Buff2[i]);
getch ( ); fclose(Fuente1); fclose(Fuente2);
exit(1);
}
}
ComDeDiff+=Leidos;
}
getch();
}
CLASE DE TEORÍA Nro 6
Página 27 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
-----------------------------------------------------------------------------------------------------------------------
/* --- TALLER DE LENGUAJES I
2014 - Inspeccionador de archivos.cpp
Este programa lee en forma binaria y en filas de 8 bytes c/u, un archivo de cualquier naturaleza. En este ejemplo se trata de un archivo de texto (el código fuente de un programa
escrito con este mismo entorno). Para el ejemplo dado, se observa que cada línea finalizar con el par CR + LF, o sea retorno de carro mas alimentación de línea.
IMPORTANTE: es de hacer notar que cuando se graba un archivo de
texto mediante fprintf( ) una cadena que finaliza
en '\0', el compilador se encarga de convertirlo en
el par CR + LF.
-------------------------------------------------------------------------------------------------------- */
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
void InspeccionarArchivo( char * );
// ----------------------------------------------------------------------------------------------------------void main()
{
char NombFuente[128] = "D:\\DISCO F\\Leng214\\Trapecios.txt";
clrscr( );
InspeccionarArchivo(NombFuente);
getch( );
}
// ---------------------------------------------------------------------------------------------------------void InspeccionarArchivo(char *NombFile)
{
const LF = 10;
const CR = 13;
FILE
int
char
int
*Fuente;
Leidos;
Buff[16];
i;
CLASE DE TEORÍA Nro 6
Página 28 de 29
Carrera de Programador Universitario & Licenciatura en Informática
TALLER DE LENGUAJES I 2015 - Dictado: Ing. Juan M. Conti
FACET de la Universidad Nacional de Tucumán.
----------------------------------------------------------------------------------------------------------------------if((Fuente=fopen(NombFile,"rb"))==NULL) {
cprintf("NO PUDO ABRIR ARCHIVO FUENTE\r\n");
getch(); return;
}
while((Leidos=fread(Buff,1,8,Fuente))!=0) {
for(i=0;i<Leidos;i++) {
if((Buff[i]==LF) || (Buff[i]==CR)) textcolor(LIGHTRED);
else textcolor(WHITE);
cprintf("%02X ",Buff[i]);
}
cprintf("\r\n");
getch();
}
fclose(Fuente);
}
// ---------------------------------------------------------------------------------------------------------------La línea:
cprintf("%02X ",Buff[i]);
establece que el contenido de Buff[ i ] saldrá por pantalla como hexadecimal con dos dígitos, rellenando con 0 cuando su valor sólo implique un dígito.
CLASE DE TEORÍA Nro 6
Página 29 de 29
Descargar