Author Topic: Modificar archivo binario en lenguaje C.  (Read 501 times)

DanielC

  • Newbie
  • *
  • Posts: 8
  • Karma: 0
    • View Profile
Modificar archivo binario en lenguaje C.
« on: Septiembre 19, 2016, 03:27:22 am »
Hola, a todos. -
Les dejo mi código para ver si me pueden ayudar con ese inconveniente que con sinceridad les digo ya me está sobrepasando, no les explico que hace el programa porque creo que no sirve en este caso, el inconveniente lo tengo en la línea 149, la función lee una línea desde el archivo, la misma debo modificarla y volverla a escribir pero como no logro retroceder el puntero al comienzo del registro, la duplica. -

Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
int  habilitado;
char ingles[30];
char espaniol[30];
int orden;
}Idiomas;

#define MAX_CAR 30

void menu( char *nombreArchivo );
long contar( char *nombreArchivo );
int contarMarcados( char *nombreArchivo );
Idiomas agregar( void );
void guardar( Idiomas idiomas, char *nombreArchivo, long numeroRegistros );
void mostrar( char *nombreArchivo );
void buscar( char *nombreArchivo );
void modificarBorrar( FILE *file, Idiomas idiomas );
void limpiar( void );
void dibujo( void );

int main( void ){
char nombreArchivo[] = "traductor.bin";

menu( nombreArchivo );

return 0;
}

void limpiar( void ){
system("cls||clear");
}

long contar( char *nombreArchivo ){

FILE *file = fopen( nombreArchivo, "ab" );
long numeroRegistros;
 
  fseek(file, 0, SEEK_END);  /* Nos situamos al final del mismo */
 
/* ftell devuelve el numero de bytes desde el principio del fichero
hasta la posicion actual que es el final del fichero */

numeroRegistros = ftell( file )/sizeof( Idiomas );
fclose( file );
 
return numeroRegistros;
}

int contarMarcados( char *nombreArchivo ){
int marcados = 0;

FILE *file = fopen( nombreArchivo, "rb" );

if( file != NULL ){
Idiomas idiomas;
rewind( file );
while( fread( &idiomas, sizeof(Idiomas), 1, file )){
if( idiomas.habilitado == 0 ){
marcados++;
}
}
}else{
printf( "\n Error al abrir %s para escritura/lectura. Finaliza el programa.", nombreArchivo );
}

fclose( file );

return marcados;
}

void menu( char *nombreArchivo ){
int opc, ok, ch, marcados;
long numeroRegistros = 0;

do{
do{
limpiar( );
numeroRegistros = contar( nombreArchivo );
marcados = contarMarcados( nombreArchivo );
dibujo();
printf( "\n Cuenta hasta el momento con [%ld] palabra(s) traducida(s).", numeroRegistros );
printf( "\n Tiene [%d] registro(s) marcado(s) para borrar.", marcados);
dibujo();
printf( "\n =============== Menu principal ===============\n"
"\n [1] - Agregar"
"\n [2] - Listar"
"\n [3] - Buscar (-> Modificar -> Borrar)"
"\n [4] - Empaquetar"
"\n [5] - Finalizar"
"\n\n ingrese opcion.....:" );

ok = scanf( "%d", &opc ) == 1 && opc > 0 && opc <= 5;
while ((ch = getchar()) != EOF && ch != '\n');
}while( !ok );


switch ( opc ){
case 1: guardar( agregar(), nombreArchivo, numeroRegistros );
break;
case 2: mostrar( nombreArchivo );
break;
case 3: buscar( nombreArchivo );
break;
}
}while( opc != 5 );
}

Idiomas agregar( void ){
Idiomas idiomas;
char *p=NULL;

idiomas.habilitado = 1;

limpiar();

printf( "\n Introduzca palabra en ingles......:" );
fgets( idiomas.ingles, MAX_CAR, stdin );
if(( p=strchr( idiomas.ingles, '\n' )) ){ *p='\0'; }

printf( "\n Introduzca traduccion al español..:" );
fgets( idiomas.espaniol, MAX_CAR, stdin );
if(( p=strchr( idiomas.espaniol, '\n' )) ){ *p='\0'; }

return idiomas;
}

void guardar( Idiomas idiomas, char *nombreArchivo, long numeroRegistros ){
FILE *file = fopen( nombreArchivo, "a+b" );
int contador=0, i;

if( file != NULL ){
numeroRegistros += 1;

if( numeroRegistros > 0 ){
Idiomas tmp;
tmp.habilitado = idiomas.habilitado;
strcpy( tmp.ingles, idiomas.ingles );
strcpy( tmp.espaniol, idiomas.espaniol);
tmp.orden = 1;

while( fread( &idiomas, sizeof(Idiomas), 1, file) ){
i = strcmp( tmp.ingles, idiomas.ingles );
if( i < 0 ){
idiomas.orden += 1;
fseek(file, (contador-1)*sizeof(Idiomas), SEEK_SET);
fwrite( &idiomas, sizeof(Idiomas), 1, file );
}else{
tmp.orden += 1;
}
contador++;
}
fwrite( &tmp, sizeof(Idiomas), 1, file );
}else{
idiomas.orden = 1;
fwrite( &idiomas, sizeof(Idiomas), 1, file );
}
}else{
printf( "\n Error al abrir %s para escritura/lectura. Finaliza el programa.", nombreArchivo );
}

fclose( file );
}

void mostrar( char *nombreArchivo ){
FILE *file = fopen( nombreArchivo, "rb" );

limpiar();

if( file != NULL ){
Idiomas idiomas;
dibujo();
printf( "\n %-30s %-30s\n", "Ingles", "Espaniol" );
while( fread( &idiomas, sizeof(Idiomas), 1, file )){
printf( "\n %-30s %-30s, %d", idiomas.ingles, idiomas.espaniol, idiomas.orden );
}
dibujo();
}else{
printf( "\n Error al abrir %s para escritura/lectura. Finaliza el programa.", nombreArchivo );
}
printf( "\n\n Pulse una tecla para continuar..." ); getchar();
fclose( file );
}

void buscar( char *nombreArchivo ){
FILE *file = fopen( nombreArchivo, "rb" );
Idiomas idiomas;
char buscar[MAX_CAR], *p=NULL;
int encontrado;

limpiar();

if( file != NULL ){
printf( "\n Ingrese la palabra a buscar....: " );
fgets( buscar, MAX_CAR, stdin );

if(( p=strchr(buscar, '\n' )) ) { *p='\0';}

while( fread( &idiomas, sizeof(Idiomas), 1, file )){
encontrado = strcmp( idiomas.espaniol, buscar );
if( encontrado != 0 ){
encontrado = strcmp( idiomas.ingles, buscar );
}
if( encontrado == 0){
break;
}
}
if( encontrado != 0 ){
printf( "\n No existe..." );
printf( "\n\n Pulse una tecla para volver al menu..." ); getchar();
}else{
modificarBorrar( file, idiomas );
}

fclose( file );
}
else{
printf( "\n Error al abrir %s para lectura. Finaliza el programa.", nombreArchivo );
}

}

void modificarBorrar( FILE *file, Idiomas idiomas ){
int opc=0, ok, ch;

do{
limpiar( );

dibujo();
printf( "\n %-30s %-30s\n", "Ingles", "Espaniol" );
printf( "\n %-30s %-30s", idiomas.ingles, idiomas.espaniol );
dibujo();

printf( "\n\n ========== Modificar/borrar registro ==========\n"
"\n 1 - Modificar"
"\n 2 - Borrar"
"\n 3 - Continuar"
"\n\n ingrese opcion.....:" );

ok = scanf( "%d", &opc ) == 1 && opc > 0 && opc <= 3;
while ((ch = getchar()) != EOF && ch != '\n');
}while( !ok );


switch ( opc ){
case 1: ;
break;
case 2: ;
break;
case 3: break;
}
}

void dibujo( void ){
int con = 0;
printf( "\n" );
while( con <= 75 ){
printf( "-" ); con++;
}
}

Espero puedan ayudarme, saludos y desde ya muchas gracias. -
Daniel

chuidiang

  • Administrator
  • Hero Member
  • *****
  • Posts: 5401
  • Karma: 11
    • View Profile
    • Apuntes de programación
Re: Modificar archivo binario en lenguaje C.
« Reply #1 on: Septiembre 19, 2016, 03:33:59 am »
Hola:

Estas preguntando una cosa muy concreta, lo de hacer retroceder el puntero del fichero para modificar un registro. Ayudaría si en vez de todo el código, pusieras sólo el trozo donde intentas hacer eso o, al menos, una indicación sobre como encontrar entre tanto código el trozo que te da problemas.

Se bueno.

DanielC

  • Newbie
  • *
  • Posts: 8
  • Karma: 0
    • View Profile
Re: Modificar archivo binario en lenguaje C.
« Reply #2 on: Septiembre 19, 2016, 03:41:31 am »
Hola, gracias por tan pronta respuesta.
Puse la línea 149 pero no sabía que no aparecía el número de líneas en este foro. -

Code: [Select]
fseek(file, (contador-1)*sizeof(Idiomas), SEEK_SET);
Saludos.
Daniel

chuidiang

  • Administrator
  • Hero Member
  • *****
  • Posts: 5401
  • Karma: 11
    • View Profile
    • Apuntes de programación
Re: Modificar archivo binario en lenguaje C.
« Reply #3 on: Septiembre 19, 2016, 05:00:47 am »
Hola:

¿Qué es lo que tiene el fichero y qué es lo que tiene que tener cuando terminas? (no todo el fichero, sólo las 3 ó 4 líneas alrededor de la de interés :)

Se bueno.

DanielC

  • Newbie
  • *
  • Posts: 8
  • Karma: 0
    • View Profile
Re: Modificar archivo binario en lenguaje C.
« Reply #4 on: Septiembre 19, 2016, 05:36:52 am »
Hola.
La idea la dejo en la captura de pantalla, lo que hago es ordenar el traductor no intercambiando los registros sino poniendo un campo que contiene el orden, seguramente con la imagen lo entenderás.



Saludos y muchas gracias.

chuidiang

  • Administrator
  • Hero Member
  • *****
  • Posts: 5401
  • Karma: 11
    • View Profile
    • Apuntes de programación
Re: Modificar archivo binario en lenguaje C.
« Reply #5 on: Septiembre 19, 2016, 10:04:47 pm »
Hola:

¿Y el fichero de texto original y el fichero de texto que quieres obtener?

Estas leyendo el fichero, en medio del bucle de lectura decides echar el contador para atrás y escribir. No sé en una sola lectura (un solo bucle de lectura) como puedes obtener esos numeros de posisicion que dices haciendo solo un bucle y un idiomas.order+=1. Eso solo te sumaria uno a los numeros que hubiera originalmente en el fichero, como mucho. Creo que es mas problema de como has planteado ese algorigmo/bucle que el fseek no funcione. Por eso mi insistencia en ver el contenido original del fichero y el fichero que obtienes (aparte el fichero que esperas)

Se bueno.

DanielC

  • Newbie
  • *
  • Posts: 8
  • Karma: 0
    • View Profile
Re: Modificar archivo binario en lenguaje C.
« Reply #6 on: Septiembre 20, 2016, 06:36:34 am »
Hola, chuidiang. -
Discúlpame por quitarte tanto tiempo, lo que pasa es que creí que era más sencillo el tema pero no resulto ser así, por lo tanto,  lo voy a intentar de otra manera. -

Muchas gracias y un abrazo.
Daniel.

 

ey