elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Trabajando con las ramas de git (tercera parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Tutorial de archivos en lenguaje C. -
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: 1 2 3 [4] Ir Abajo Respuesta Imprimir
Autor Tema: Tutorial de archivos en lenguaje C. -  (Leído 15,752 veces)
NOB2014


Desconectado Desconectado

Mensajes: 366



Ver Perfil
Re: Tutorial de archivos en lenguaje C. -
« Respuesta #30 en: 15 Septiembre 2016, 00:21 am »

Hola, a todos.
Alberto, muy interesante lo que propones lo voy a llevar a la práctica para ver si lo logro, en realidad muy interesante. -
A continuación, dejo una manera que me vino a la mente y parece que puede dar resultado, lo dejo a su consideración para que me digan si lo puedo mejorar y que les parece la velocidad que se puede obtener al ordenar de esta manera. -

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int main(void){
  5. int numeros[10] = {0}, ordenar[10] = {0}, ingreso = 0;
  6. int i, j;
  7.  
  8. for( i=0; i<10; i++ ){
  9. printf(" \n Ingrese un entero (cero para finalizar)....: ");
  10. scanf("%d", &ingreso);
  11.  
  12. if( ingreso == 0 ){
  13. break;
  14. }
  15.  
  16. numeros[i] = ingreso;
  17. ordenar[i] = 1;
  18.  
  19. if( i > 0 ){
  20. j=0;
  21. while( j < i ){
  22. if( ingreso < numeros[j] ){
  23. ordenar[j] += 1;
  24. }else{
  25. ordenar[i] += 1;
  26. }
  27. j++;
  28. }
  29. }
  30. }
  31.  
  32. printf("\n\n  Numeros ==> ");
  33. for( i=0; i<10; i++ ){
  34. printf("%2d ", numeros[i]);
  35. }
  36. printf("\n  Ordenar ==> ");
  37. for( i=0; i<10; i++ ){
  38. printf("%2d ", ordenar[i]);
  39. }
  40.  
  41. return 0;
  42. }
     
     

Como comprenderán es solo una practica luego tengo que insertarlo en el programa de archivo binario. -

Saludos.


En línea

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.-
crack81

Desconectado Desconectado

Mensajes: 222



Ver Perfil
Re: Tutorial de archivos en lenguaje C. -
« Respuesta #31 en: 15 Septiembre 2016, 02:42 am »

Hola esta bien tu código pero me pregunto, necesitas un arreglo para almacenar los registro y otro del mismo tamaño para saber en que posición se encontrarían ordenados? siendo muy estrictos realmente no es un método de ordenamiento ya que los datos siguen como en su estado original.

Pero bueno tomemos tu algoritmo como valido y comparemoslo frente a otros algoritmos amplia-mente documentados y como serian bubble sort y Quick sort como se comporta

Para ello necesitamos algunas subrutinas que nos midan el tiempo de procesamiento de nuestros algoritmos lamentablemente hacer esto no siempre es muy preciso y depende del sistema operativo y arquitectura de la computadora donde se ejecuten estas pruebas.

La primera prueba que vamos a hacer es con tu algoritmo para ello lo encapsule en una función y decidí tomar algunas muestras

Código
  1. #include <stdio.h>
  2. #include<windows.h>
  3. #include <time.h>
  4.  
  5. double performancecounter_diff(LARGE_INTEGER *a, LARGE_INTEGER *b){
  6.    LARGE_INTEGER freq;
  7.    QueryPerformanceFrequency(&freq);
  8.    return (double)(a->QuadPart - b->QuadPart) / (double)freq.QuadPart;
  9. }
  10.  
  11.  
  12.  
  13. void rellenarOrdenarDatos(int numeros[],int ordenar[],int tamano){
  14.    int i,j,ingreso;
  15.    srand(time(NULL));
  16.  
  17.    for( i=0; i<tamano; i++){
  18.  
  19.        ingreso = rand()%100;
  20.        numeros[i]=ingreso;
  21.        ordenar[i] = 1;
  22.  
  23.        if(i>0){
  24.            j=0;
  25.            while(j<i){
  26.                if( ingreso < numeros[j] ){
  27.                    ordenar[j] += 1;
  28.                }
  29.                else{
  30.                    ordenar[i] += 1;
  31.                }
  32.                j++;
  33.            }
  34.        }
  35.    }
  36. }
  37.  
  38. int main()
  39. {
  40.    const int TAMANO=15000;
  41.    int *arreglo=malloc(sizeof(int)*TAMANO);
  42.    int *ordenar=malloc(sizeof(int)*TAMANO);
  43.  
  44.    LARGE_INTEGER t_ini, t_fin;
  45.    double secs;
  46.  
  47.    QueryPerformanceCounter(&t_ini);
  48.  
  49.    rellenarOrdenarDatos(arreglo,ordenar,TAMANO);
  50.  
  51.    QueryPerformanceCounter(&t_fin);
  52.  
  53.    secs = performancecounter_diff(&t_fin, &t_ini);
  54.    printf("%.16g milliseconds\n", secs * 1000.0);
  55.  
  56.    free(arreglo);
  57.    free(ordenar);
  58.  
  59.    return 0;
  60. }

Entre las muestras que obtuve fueron estos tiempos en milisegundos
Citar
937.9348
1006.7837
984.6807
917.7779
1013.7831
993.5917

Ahora la prueba con BubbleSort

Código
  1. #include <stdio.h>
  2. #include<windows.h>
  3. #include <time.h>
  4.  
  5. double performancecounter_diff(LARGE_INTEGER *a, LARGE_INTEGER *b){
  6.    LARGE_INTEGER freq;
  7.    QueryPerformanceFrequency(&freq);
  8.    return (double)(a->QuadPart - b->QuadPart) / (double)freq.QuadPart;
  9. }
  10.  
  11.  
  12.  
  13.  
  14. void rellenarArreglo(int numeros[],unsigned int tamano){
  15.    srand(time(NULL));
  16.    int i=0;
  17.  
  18.    for(i=0; i<tamano; i++)
  19.    {
  20.        int r = rand()%100+1;
  21.        numeros[i]=r;
  22.    }
  23. }
  24.  
  25. void bubbleSort(int numeros[],int tamano){
  26.    int i,j,temp;
  27.    for (i=1; i<tamano; i++){
  28.      for(j=0 ; j<tamano - 1; j++){
  29.         if (numeros[j] > numeros[j+1]){
  30.            temp = numeros[j];
  31.            numeros[j] = numeros[j+1];
  32.            numeros[j+1] = temp;
  33.         }
  34.      }
  35.    }
  36. }
  37.  
  38.  
  39.  
  40. int main()
  41. {
  42.    const int TAMANO=15000;
  43.    int *arreglo=malloc(sizeof(int)*TAMANO);
  44.  
  45.  
  46.    LARGE_INTEGER t_ini, t_fin;
  47.    double secs;
  48.  
  49.    QueryPerformanceCounter(&t_ini);
  50.  
  51.    rellenarArreglo(arreglo,TAMANO);
  52.    bubbleSort(arreglo,TAMANO);
  53.  
  54.    QueryPerformanceCounter(&t_fin);
  55.  
  56.    secs = performancecounter_diff(&t_fin, &t_ini);
  57.    printf("%.16g milliseconds\n", secs * 1000.0);
  58.  
  59.    free(arreglo);
  60.  
  61.  
  62.    return 0;
  63. }

Utilizando el algoritmo bubble sort el tiempo de procesamiento fue mas alto por ende menos optimo aproximadamente 1500 milsegundos en promedio, en este caso te debo los tiempos exactos

Por ultimo utilize el algoritmo Quick Sort y la diferencia fue abismal
El siguiente codigo es similar al anterior salvo por el metodo de ordenamiento

Código
  1. void qs(int lista[],int limite_izq,int limite_der)
  2. {
  3.    int izq,der,temporal,pivote;
  4.  
  5.    izq=limite_izq;
  6.    der = limite_der;
  7.    pivote = lista[(izq+der)/2];
  8.  
  9.    do{
  10.        while(lista[izq]<pivote && izq<limite_der)izq++;
  11.        while(pivote<lista[der] && der > limite_izq)der--;
  12.        if(izq <=der)
  13.        {
  14.            temporal= lista[izq];
  15.            lista[izq]=lista[der];
  16.            lista[der]=temporal;
  17.            izq++;
  18.            der--;
  19.  
  20.        }
  21.  
  22.    }while(izq<=der);
  23.    if(limite_izq<der){qs(lista,limite_izq,der);}
  24.    if(limite_der>izq){qs(lista,izq,limite_der);}
  25.  
  26. }
  27.  
  28. void quicksort(int lista[],int n)
  29. {
  30.    qs(lista,0,n-1);
  31. }
  32.  
  33.  
  34.  
  35. int main()
  36. {
  37.    const int TAMANO=15000;
  38.    int *arreglo=malloc(sizeof(int)*TAMANO);
  39.  
  40.  
  41.    LARGE_INTEGER t_ini, t_fin;
  42.    double secs;
  43.  
  44.    QueryPerformanceCounter(&t_ini);
  45.  
  46.    rellenarArreglo(arreglo,TAMANO);
  47.    quicksort(arreglo,TAMANO);
  48.  
  49.    QueryPerformanceCounter(&t_fin);
  50.  
  51.    secs = performancecounter_diff(&t_fin, &t_ini);
  52.    printf("%.16g milliseconds\n", secs * 1000.0);
  53.  
  54.    free(arreglo);
  55.  
  56.  
  57.    return 0;
  58. }

Aqui una lista de tiempos obtenidos
Citar
2.1082
2.2769
2.1349
2.1203
2.0972
2.1325

En promedio 2 mili-segundos el tiempo de procesamiento

En conclusion yo te recomendaria usar une metodo de ordenamiento ya que ademas de que evitas reservar memoria inecesaria el performance es mejor.

SI hay dudas o no estas de acuerdo con algo no dudes en hacermelo saber.
Saludos.... :silbar:






En línea

Si C/C++ es el padre de los lenguajes entonces ASM es dios.
NOB2014


Desconectado Desconectado

Mensajes: 366



Ver Perfil
Re: Tutorial de archivos en lenguaje C. -
« Respuesta #32 en: 15 Septiembre 2016, 15:52 pm »

Hola, crack81, como estas.
Tal vez no leíste por donde venia el tema o no me supe explicar en el post anterior. -

Citar
Hola esta bien tu código pero me pregunto, necesitas un arreglo para almacenar los registro y otro del mismo tamaño para saber en que posición se encontrarían ordenados? siendo muy estrictos realmente no es un método de ordenamiento ya que los datos siguen como en su estado original.
Lo que quiero lo vas a entender mejor en la imagen que dejo a continuación, es para un traductor inglés/español y ordenándolo de esta manera por Ej. no necesito hacer un archivo temporal o en memoria para hacer que se muestre en un determinado orden, puedo ordenar el archivo por las palabras en inglés, en español y de forma natural, como se ingresaron los datos. -
Ahora desconozco si esto es más lento o rápido que tener los datos ordenados físicamente, lo que estoy seguro es que no necesito 5 archivos por si hay 5 campos por ordenar, simplemente se agregan tantas columnas como sea necesarias y listo. -
De cualquier manera por el momento no deseo competir con creadores de bases de datos, aunque debo reconocer que es mi fuerte. -



Saludos, un abrazo.

En línea

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
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.705


🏴 Libertad!!!!!


Ver Perfil WWW
Re: Tutorial de archivos en lenguaje C. -
« Respuesta #33 en: 15 Septiembre 2016, 16:57 pm »

Tu idea esta bien, te sirve bastante si no quieres estar moviendo los registros "fisicamente" en su posicion del archivo.

Asi solo guardas en un arreglo externo que el registro X del archivo esta en el orden TAL.

Y podrias implementar una busqueda casi binaria por ejemplo tienes 1000 Registros y buscas por la letra T o no se la palabra tocar, vez quien es el registro 500 y si la palabra tocar es mayor te desplazas 250 registros mas adelante y buscas en el registro 750 y si es mayor o menor te desplazas 125 registros adelante o atras y asi sucesivamente. Para buscar rapidamente la palabra tal....

Saludos!

En línea

NOB2014


Desconectado Desconectado

Mensajes: 366



Ver Perfil
Re: Tutorial de archivos en lenguaje C. -
« Respuesta #34 en: 17 Septiembre 2016, 14:39 pm »

Hola, a todos. -
Créanme que probé de muchas maneras pero no me funciona, el error lo tengo en el último campo, no puedo hacer que se modifique, les dejo solamente la función guardar para no hacerlo tan largo, descarto que alguien de Uds. me podrá dar la solución sin tener que correr el programa. - 
Alberto me interesa lo de la búsqueda casi binaria, lo voy a practicar. -

Código
  1. void guardar( Idiomas idiomas, char *nombreArchivo, long numeroRegistros ){
  2. FILE *file = fopen( nombreArchivo, "ab" );
  3. Idiomas tmp;
  4. tmp.habilitado = idiomas.habilitado;
  5. strcpy( tmp.ingles, idiomas.ingles );
  6. strcpy( tmp.espaniol, idiomas.espaniol);
  7. tmp.orden = 1;
  8.  
  9.  
  10. if( file != NULL ){
  11. numeroRegistros += 1;
  12.  
  13. if( numeroRegistros > 1 ){
  14. fseek( file, 0, SEEK_SET );
  15. while( fread( &idiomas, sizeof(Idiomas), 1, file )){
  16. if( strcmp( tmp.ingles, idiomas.ingles ) < 0 ) {
  17. idiomas.orden += 1;
  18. fwrite( &idiomas, sizeof(Idiomas), 1, file );
  19. }else{
  20. tmp.orden += 1;
  21. }
  22. }
  23. }
  24. fwrite( &tmp, sizeof(Idiomas), 1, file );
  25. }else{
  26. printf( "\n Error al abrir %s para escritura/lectura. Finaliza el programa.", nombreArchivo );
  27. }
  28.  
  29. fclose( file );
  30. }
  31.  



Saludos y desde ya muchas gracias. -
En línea

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
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.705


🏴 Libertad!!!!!


Ver Perfil WWW
Re: Tutorial de archivos en lenguaje C. -
« Respuesta #35 en: 17 Septiembre 2016, 22:23 pm »

No estoy seguro de cuales son los datos ingresados pero el problema puede ser el strcmp, ya que solo lo tienes mejor que cero y strcmp puede devolver -1, 0 o 1 segun sea menor, igual o mayor deberias de cambiarlo por !=

Código
  1. strcmp( tmp.ingles, idiomas.ingles ) != 0

Saludos!
En línea

NOB2014


Desconectado Desconectado

Mensajes: 366



Ver Perfil
Re: Tutorial de archivos en lenguaje C. -
« Respuesta #36 en: 18 Septiembre 2016, 14:58 pm »

Hola. -
alberto creo que el problema era la apertura del archivo y en realidad nunca se ejecutaba el bucle, después de tanta práctica logre hacer que funcionara pero o sorpresa cada vez que tenia que modificar el orden de la palabra grabada en el archivo se duplicaba y en realidad lo que necesitaba era modificarla, ahora el problema que tengo es que no logro regresar el puntero file al comienzo de la  linea donde está parado para modificarla/sobre escribirla. -

Código
  1. file -= sizeof( Idiomas ); //es algo que se me antojo de tanto practicar, pero no me funciono. -

¿Me podrían decir porque la siguiente línea no mueve el cursor del archivo al comienzo de la misma?

Código
  1. fseek(file, -1L*sizeof(Idiomas), SEEK_CUR);

Código
  1. void guardar( Idiomas idiomas, char *nombreArchivo, long numeroRegistros ){
  2. FILE *file = fopen( nombreArchivo, "a+b" );
  3. int i=0;
  4.  
  5. if( file != NULL ){
  6. numeroRegistros += 1;
  7.  
  8. if( numeroRegistros > 1 ){
  9. Idiomas tmp;
  10. tmp.habilitado = idiomas.habilitado;
  11. strcpy( tmp.ingles, idiomas.ingles );
  12. strcpy( tmp.espaniol, idiomas.espaniol);
  13. tmp.orden = 1;
  14.  
  15. fseek (file, 0L, SEEK_SET);
  16. while( fread( &idiomas, sizeof(Idiomas), 1, file) ){
  17. i = strcmp( tmp.ingles, idiomas.ingles );
  18. if( i < 0 ){
  19. idiomas.orden += 1;
  20. printf("\n antes...: %p", file);
  21. file -= sizeof( Idiomas );
  22. // fseek(file, -1L*sizeof(Idiomas), SEEK_CUR);
  23. printf("\n despues.: %p", file); getchar();
  24. fwrite( &idiomas, sizeof(Idiomas), 1, file );
  25. }else{
  26. tmp.orden += 1;
  27. }
  28. }
  29. fwrite( &tmp, sizeof(Idiomas), 1, file );
  30. }else{
  31. idiomas.orden = 1;
  32. fwrite( &idiomas, sizeof(Idiomas), 1, file );
  33. }
  34. }else{
  35. printf( "\n Error al abrir %s para escritura/lectura. Finaliza el programa.", nombreArchivo );
  36. }
  37.  
  38. fclose( file );
  39. }
  40.  
Saludos.
En línea

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
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.705


🏴 Libertad!!!!!


Ver Perfil WWW
Re: Tutorial de archivos en lenguaje C. -
« Respuesta #37 en: 18 Septiembre 2016, 16:52 pm »

Nunca lo he provado de esa forma prefiero manejarlo desde el SEEK_SET para hacerlo desde el inicio del archivo. lo que me gusta hacer es tener un contador para saber cual es el numero de registro actual y si quiero regrersar al que previamente lei lo que hago es

Código
  1. fseek(file, (contador-1)*sizeof(Idiomas), SEEK_SET);

Tendria que probar con la posición SEEK_CUR como lo mencionas.

Saludos!
En línea

NOB2014


Desconectado Desconectado

Mensajes: 366



Ver Perfil
Re: Tutorial de archivos en lenguaje C. -
« Respuesta #38 en: 21 Septiembre 2016, 00:47 am »

Hola. -
una consulta, si tengo un archivo con palabras desordenadas y luego las ordeno en un arreglo de estructura, como debo hacer para escribir en el archivo nuevamente, tengo que borrarlo primero o puedo sobrescribir registro por registro. - 


desde ya muchas gracias.
« Última modificación: 21 Septiembre 2016, 02:39 am por NOB2014 » En línea

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
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.705


🏴 Libertad!!!!!


Ver Perfil WWW
Re: Tutorial de archivos en lenguaje C. -
« Respuesta #39 en: 21 Septiembre 2016, 16:19 pm »

De las 2 formas es valido.

Si es la misma cantidad de registros no hay por que preocuparse...

Se mueve a la posicion 0 con fseek y se escribe registro por registro.

En caso de que quieraa reescribir (borrar y escribir)

Solo hay que cerrar el archivo actual y abrir uno nuevo con el mismo nombre y en modo "w" o "wb" segun sea de texto o binario y asi escribir registro por registro en el archivo nuevo.

Saludos
En línea

Páginas: 1 2 3 [4] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines