Tutorial de archivos en lenguaje C. -

Iniciado por NOB2014, 26 Agosto 2016, 14:51 PM

0 Miembros y 1 Visitante están viendo este tema.

NOB2014

#20
Estoy probando un montón de maneras y no me funciona, te dejo algunos datos para ver si me podes dar la solución. -

Esto es lo que sale al abrir un terminal
Citardaniel@daniel-H81M-S1 ~ $

Y esta es la ruta(carpetas) completa...
.../Escritorio/Prueba/Archivos Daniel/Escribir/pruebaE.txt

Y donde esta el programa con el que estoy trabajando es:
.../Escritorio/Prueba/Archivos Daniel/Leer

Saludos.


Bueno ya lo logre con el comando locate.
FILE *pArchivo = fopen( "/home/daniel/Escritorio/Prueba/Archivos Daniel/Escribir/pruebaE.txt", "r" ); //Comando locate

pero vaya sorpresa me imprime solo el primer registro (todos los campos) pero no salta al segundo, como que se quedaría en un bucle infinito, practico un poco y si no lo logro les consulto. -

Buen día. -
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

MAFUS

Usa la ruta completa: "/home/daniel/Escritorio/Prueba/Archivos Daniel/Escribir/pruebaE.txt"
O la ruta relativa: "../Escribir/pruebaE.txt"

La ruta completa empieza en el directorio raíz /, después pasas al directorio que guarda los archivos de usuarios home, el nombre de usuario del sistema daniel y a partir de allí moverte por árbol de directorios hasta el archivo.

Las rutas relativas parten desde donde se encuentra el programa y para subir al directorio padre debes usar los dos puntos ..; una vez llegues al directorio común escribe el resto de la ruta a donde quieras llegar. Nota: para ir retrocediendo en el árbol, usa ../../ tantas veces como sea necesario.

NOB2014

#22
5 - Leer/escribir

Hola.
Hoy estoy un poco cargoso, espero sepan comprender mi ansiedad por resolver esto. -
Les dejo los 2 códigos para escribir en archivos y leer desde un archivo, quisieran que lo revisen con tiempo y me digan que estoy asiendo mal, en realidad escribir me parece que funciona bien, en cuanto a leer lee solamente la primer linea y se produce un bucle infinito. -  
Una cosita mas, la línea 39 del archivo leer no me place para nada, ¿con que otra función la puedo reemplazar?. -
MAFUS, gracias por el aporte y que agrado da leerte nuevamente. -

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

void limpiar( void );
void leer( FILE *pArchivo );

int main( void ){

// FILE *pArchivo = fopen( "/home/daniel/Escritorio/Prueba/Archivos Daniel/Escribir/pruebaE.txt", "r" ); //Comando locate
FILE *pArchivo = fopen( "../Escribir/pruebaE.txt", "r" );

if( pArchivo != NULL ){
leer( pArchivo );

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


return 0;

}

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


void leer( FILE *pArchivo ){
int orden=0;
char nombre[30];
double salario;

printf( "\n\n Orden  Nombre          Salario\n\n" );

while( !feof(pArchivo) ){
fscanf(pArchivo,"%d\t%[^\n]\t%lf",&orden,nombre,&salario);
printf(" %d\t%-10s\t%lf",orden,nombre,salario);
}
}


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

#define MAX_CAR 30

void limpiar( void );
void agregar( FILE *pArchivo );

int main( void ){

FILE *pArchivo = fopen( "pruebaE.txt", "a+" );

if( pArchivo != NULL ){
agregar( pArchivo );

fclose( pArchivo );
}else{
printf( "\n Error al abrir %s para escritura/lectura. Finaliza el programa.", "pruebaE.txt" );
}


return 0;

}

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


void agregar( FILE *pArchivo ){
int n = 1, ch, orden=0, escrito;
char nombre[MAX_CAR], caracter, *p=NULL;
double salario;

while ( !feof ( pArchivo ) ){
caracter = getc( pArchivo );
if( caracter == '\n' )
orden++;
}

do{
limpiar();
orden++;
printf( "\n\n El proximo empleado es el numero..: %d", orden );
printf( "\n\n Introduzca 0 para finalizar mayor para continuar.....:" );
scanf( "%d", &n );
while ((ch = getchar()) != EOF && ch != '\n');
if( n > 0 ){
printf( "\n Introduzca el NOMBRE del empleado.....:" );
fgets( nombre, MAX_CAR, stdin );
if(( p=strchr(nombre, '\n' ))){
*p='\0';
}
printf( "\n Introduzca el SALARIO del empleado....:" );
scanf( "%lf", &salario );
while ((ch = getchar()) != EOF && ch != '\n');

escrito = fprintf( pArchivo, "%d\t%s\t%lf\n", orden, nombre, salario );
}
if( escrito < 1 ){
printf( "\n ERROR!!! No se pudieron guardar los datos en el archivo."
"\n Pulse una tecla para continuar..."); getchar();
}
}while( n > 0 );
}


Un abrazso.
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

MAFUS

En el primer código cambia:
while( !feof(pArchivo) ){
    fscanf(pArchivo,"%d\t%[^\n]\t%lf",&orden,nombre,&salario);
    printf(" %d\t%-10s\t%lf",orden,nombre,salario);
}


por
fscanf(pArchivo,"%d\t%30[^\t]\t%lf",&orden,nombre,&salario);
while( !feof(pArchivo) ){
    printf(" %d\t%-10s\t%0.2lf\n",orden,nombre,salario);
    fscanf(pArchivo,"%d\t%30[^\t]\t%lf",&orden,nombre,&salario);
}


La cadena de control de fscanf ha cambiado nombre ahora recibirá un máximo de 30 caracteres, además se detendrá la lectura de nombre cuándo encuentre una tabulación (que es tu separador), no el carácter de nueva línea (que no puede existir en esa posición. También se cambia el orden de las lecturas en el buche, así no imprimirás por duplicado la última lectura.

NOB2014

#24
6 - Buscar

Hola, muy buen día para todos. -
Tengo algo mal echo en la función strcmp que no logro discernir, estuve consultando en un montón de páginas y tal vez tenga que ver con cadena constantes y no pero no logro hacer que funcione, si lo pongo a mano por Ej.:
encontrado = strcmp( espaniol, "hogar" );
el resultado es correcto. -
MAFUS, maravilloso lo tuyo, funciona a la perfección. -

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

#define MAX_CAR 30

void buscarCampo( FILE *pArchivo );


int main( void ){

FILE *pArchivo = fopen( "../Escribir/pruebaE.txt", "r" );

if( pArchivo != NULL ){
buscarCampo( pArchivo );

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


return 0;
}

void buscarCampo( FILE *pArchivo ){
int encontrado=0, orden;
char ingles[MAX_CAR], espaniol[MAX_CAR], buscar[MAX_CAR], *p=NULL;

printf( "\n Intoduzca la palabra a buscar.....: " );
fgets( buscar, MAX_CAR, stdin );
if(( p=strchr(ingles, '\n' ))){
*p='\0';
}

while( !feof(pArchivo) ){
fscanf(pArchivo,"%d\t%30[^\t]\t%30[^\n]",&orden, ingles, espaniol);
encontrado = strcmp( espaniol, buscar );
if( encontrado != 0 ){
encontrado = strcmp( ingles, buscar );
}
if( encontrado == 0){
printf( "\n\n Orden  Ingles                          Espaniol\n\n" );
printf(" %d\t%-30s\t%-30s\n",orden, ingles, espaniol);
break;
}
}
if( encontrado != 0 ){
printf( "\n No existe..." );
}
}


Saludos y muchas gracias. -
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

MAFUS

Línea 31:
Te has equivocado de puntero. En vez de ingles, debe ser buscar.

NOB2014

#26
 7 - Borrar registro


Hola, que tengan un muy buen día. -
El tema pasa ahora por borrar un registro del archivo y me gustaría que me den su criterio para hacer esta operación, yo he leído que hay 2 maneras de hacerlo, la primera consiste en tener un campo para indicar si el registro está borrado o no y en algún momento borrar todos los marcados para dicho fin, la segunda es hacer un bucle e ir copiando cada registro en un archivo temporal (salteando el elegido para borrar) y luego re nombrarlo con el nombre original, . -
Si tengo unos 15.000 registros cual de los 2 métodos utilizarían, o tal vez haya alguna otra manera más eficiente que desconozco. -
Una pregunta más, cual lejos está un archivo de transformarse en una tabla o base de datos. -

Saludos
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

AlbertoBSD

CitarSi tengo unos 15.000 registros cual de los 2 métodos utilizarían, o tal vez haya alguna otra manera más eficiente que desconozco

Si tienes esa cantidad de registros yo utilizaria la primera opcion que dijiste, tener un campo donde este marcado si es registro activo, o eliminado.

El detalle esta en que dado que estas usando registros de longitud variable (Modo texto) y no modo binario es la opcion mas adecuada.

Tendrías que tener un programa adiconal que haga el trabajo pesado (Optimizar la base de datos) quitando los registros marcados como eliminados para NO ocupar mas espacio del necesario.

Con registros binarios (DE LONGITUD FIJA) es mas facil ya que es mas rapido dejar un segmento de X tamaño en ceros (NULL) y posteriormente ocuparlo con alguno de los registros nuevos.

Saludos!
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

NOB2014

#28
8 - Ordenar

Hola, gente. -
Una vez más con una duda sobre archivos ahora binario, lo que quiero hacer es por cada ingreso que quede ordenado, también podría ser ordenar todo el archivo cada vez que sea necesario, en definitiva, lo que necesito es que me den alguna idea de como hacerlo y que tengan en cuenta que aproximadamente puede contener unos 15.000 registros. -  
muchas gracias Alberto por las ideas del post anterior.

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

typedef struct {
int  habilitado;
char ingles[30];
char espaniol[30];
}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 );
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, "r" );
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 );
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 ){
FILE *file = fopen( nombreArchivo, "ab" );

if( file != NULL ){
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", idiomas.ingles, idiomas.espaniol );
}
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++;
}
}


Saludos.
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

AlbertoBSD

Si lo que quieres es ordenarlos mientras lo vas guardando de uno en uno, tendrias que modifciar tu funcion guardar, hay algunos algoritmos de ordenamientos excelentes para tu aplicacion. El mas recomendado es el de biblioteca...

La idea basica es abstraer el sistema de Estantes usados en las bibliotecas para acomodar libros, algunos estantes estan llenos y otros a media capacidad Imaginemos que tenemos un sistema de registro (Donde esta el libro con X autor, donde empiezan las palabras con Z etc...)

La idea es por ejemplo, si vas a manejar un unico archivo, (ahorita vacio por el moemento) y llega una registro con la letra A o lo que sea... lo guardas en la posición 0, pero dejas libre la posición 1, esto es:
Tu archivo tendrá actualmente espacio para 2 registros (Posición 0 y posicion 1).

Llega un nuevo registro con la letra B, este lo colocas en la posición 2 y dejas la posicion 3 libre.

Entonces si en algun punto  llega un nuevo registro con la letra A lo agregas en la posición 1, agregas un registro blanco al final y  mueves los demás 1 registro hacia adelante cantidad de posiciones hacia adelante, y asi sucesivamente.

Tambien tendrias que tener un registro que te diga que la letra A empieza en X posicion y la B en tal posicion.

Lo anterior es la idea vaga

Mas info
https://es.wikipedia.org/wiki/Algoritmo_de_ordenamiento

https://es.wikipedia.org/wiki/Library_sort
CitarSupón que un bibliotecario almacene sus libros alfabéticamente en una estante, empezando por la A desde la izquierda, y continuando a la derecha a lo largo del estante sin espacios entre los libros hasta que termine por la Z. Si el bibliotecario adquiere un libro nuevo que pertenece a la sección B, una vez que encuentra el espacio correcto en la sección B, tiene que mover cada libro a partir de ese hasta el último libro en la sección Z para abrir espacio al libro nuevo. Esto es ordenación por inserción. Sin embargo, si dejara un espacio vacío después de cada letra, mientras hubiese un espacio vacío después de B, sólo tuviera que mover unos cuantos libros para poder hubicar el nuevo libro. Esto es el principio básico de Library Sort.
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW