Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - AlbertoBSD

#1621
El blog del n4rco  ;-) ;-)

Realmente despues de eso ya nada es lo mismo, o cuando entraa a 4chan y preguntas por imagenes perturbadoras debes en cuando alguna imagen te hace levantar la ceja
#1622
He pasado mucho tiempo en foros similares y he visto gran cantidad de cosas que actualmente no me sorprenden mucho
#1623
Cita de: NOB2014 en  4 Mayo 2016, 20:03 PM
¿Que es más eficiente, utilizar array o memoria dinámica?, para el caso. - 

Es preferible usar memoria dinámica si no sabes a prior la cantidad de datos que vas a manejar, asi solo reservas memoria para los datos que realmente se usan.

printf("\n Ingresa un numero entero(maximo %d  => 0 finaliza )....: ", INT_MAX);

Claro ejemplo si no sabes cuantos datos vana meter es preferible reservar memoria dinamicamente.

Si por el contrario usas, un numero fijo, no hay problema de usar un array estatico

Saludos!
#1624
Cita de: boctulus en  4 Mayo 2016, 20:10 PM
Creo puede funcionar para archivos binarios donde generalmente la cadena_a_reemplazar y el reemplazo son de longitudes iguales

Para un archivo de texto, podrias querer cambiar una palabra corta por una larga (con probabilidad de 50% de que ocurra) y creo tu programa dejaria un hueco con basura... me tocaria revisalor mejor.

Basura como tal no, pero si se concatenaría la cadena con algun valor adyacente. Y e programa hacia cosas raras, por ejemplo como el registro esta delimitado por Enter y si se borra este se concatenaría con el siguiente registro.

El siguiente codigo genera una base de datos random para prueba

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

int main() {
FILE *f;
char *linea;
int i = 0,j;
int len,valor;
int max = 10000000;
time_t inicio, fin;
srand(time(NULL));
f = fopen("bd","w");
printf("Escribiendo archivo por favor espere son %i de registros\n",max);
inicio = time(NULL);
while(i < max) {
len = 40 + rand() % 20;
j = 0;
linea = calloc(len,1);
while(j < len) {
linea[j] = (char) 97 + rand()%26;
j++;
}
valor = rand();
fprintf(f,"%s*%i\n",linea,valor);
free(linea);
i++;
}
fin = time(NULL);
printf("tiempo de escritura %lu\n",fin-inicio);
fclose(f);
}



Tarda 52 segundos en escribir el archivo (En mi sistema) y incluye el tiempo de creacion del texto random, supongo que sera menor si el texto ya esta creado El archivo pesa sobre 500 MB
#1625
Ya esta terminado estaba modificando la variable resultados y no la de lineas

La opciones fue guardar las lineas del archivo en un arragle

char **lines;

y despues de modificar el total del stock crear una nueva linea y liberar la previa.


printf("%s", nueva_linea); // ACAA!! nueva_linea es la que debe reemplazar a
free(lines[map[opcion-1]]);
lines[map[opcion-1]] = nueva_linea;


Posteriormente escribir el archivo de nuevo

fp = fopen("bd","w");
while(j < i) {
fprintf(fp,"%s\n",lines[j]);
free(lines[j]);
j++;
}
fclose(fp);


UND3R la solucion mostrada no es el a mas viable  para archivos de gran tamaño.

Otra solucion es Tener una structura fija


struct registro{
 char campo1[300];
 int numero;
};


Asiempre seran X cantidad de bytes y no sera necesario escribir el archivo completo cada que se modifique algo, la operacion seria practicamente instantanea y podrias tener archivos del tamaño que quieras.
#1626
A ver implemente una forma de reescribir todo el archivo, me tome de la liberar de cambiar algunas cosas..

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include<sys/stat.h>

char **resultados;
char **lines;
char *nueva_linea;
int *map;

int count = 0;

char** str_split(char* a_str, const char a_delim){
    char** result    = 0;
    size_t count     = 0;
    char* tmp        = a_str;
    char* last_comma = 0;
    char delim[2];
    delim[0] = a_delim;
    delim[1] = 0;
    while (*tmp)
    {
        if (a_delim == *tmp)
        {
            count++;
            last_comma = tmp;
        }
        tmp++;
    }
    count += last_comma < (a_str + strlen(a_str) - 1);
    count++;
    result = malloc(sizeof(char*) * count);
    if (result)
    {
        size_t idx  = 0;
        char* token = strtok(a_str, delim);
        while (token)
        {
            assert(idx < count);
            *(result + idx++) = strdup(token);
            token = strtok(0, delim);
        }
        assert(idx == count - 1);
        *(result + idx) = 0;
    }
    return result;
}

off_t fsize(char *filename) {
struct stat st;
if (stat(filename, &st) == 0)
return st.st_size;
return -1;
}

void mostrarProducto(){
int i;
printf("%i coincidencias encontradas...\n\n", count);
for(i = 0; i < count; i++){
printf("%i) %s\n", i+1, resultados[i]);
}
printf("Por favor, seleccione una opcion: ");
}

void seleccionarProducto(){
int nuevo_stock,opcion;

char** resultado_split;
scanf("%i", &opcion);
printf("%s", resultados[opcion-1]);

resultado_split = str_split(resultados[opcion-1], '*');

printf("\nEl stock actual del producto es: %s\nPor favor introduzca el nuevo stock:",resultado_split[1]);
scanf("%i", &nuevo_stock);
nueva_linea = calloc(20+strlen(resultado_split[0]),1);
sprintf(nueva_linea,"%s*%i",resultado_split[0],nuevo_stock);
free(resultado_split[2]);
free(resultado_split[1]);
free(resultado_split);
printf("%s", nueva_linea); // ACAA!! nueva_linea es la que debe reemplazar a
free(lines[map[opcion-1]]);
lines[map[opcion-1]] = nueva_linea;
}

void buscarProducto(char * codProducto){
FILE * fp;
char *file_buff;
    size_t len = 0;
int i = 0, j = 0;
len = fsize("bd");
file_buff =  calloc(len+1,sizeof(char));
fp = fopen("bd", "r");
    if (fp == NULL)
        exit(EXIT_FAILURE);

fread(file_buff,sizeof(char),len,fp);
fclose(fp);
lines = str_split(file_buff,'\n');
memset(file_buff,0,len);
free(file_buff);
while(lines[i] != NULL) {
printf("Examinando linea %i: %s\n",i,lines[i]);
if(strstr(lines[i],codProducto) != NULL) {
printf("Coinciendia %s encontrada en linea %i, copiando apuntador a resultado %i\n",codProducto,i,count);
resultados = realloc(resultados,sizeof(char*)*count+1);
map = realloc(map,sizeof(int)*count+1);
resultados[count] = lines[i];
map[count] = i;
count++;
}
i++;
}
if(count != 0){
mostrarProducto(count);
seleccionarProducto();
}else{
printf("No se ha encontrado el producto!");
}
j = 0;
fp = fopen("bd","w");
while(j < i) {
fprintf(fp,"%s\n",lines[j]);
free(lines[j]);
j++;
}
fclose(fp);
    exit(EXIT_SUCCESS);
}


int main(){
buscarProducto("h65t");
exit(EXIT_SUCCESS);
}



Falla al momento de reescribir el campo seleccionado, todavía estoy depurando...

#1627
Todo depende del método que se use para escribir en el el archivo por ejemplo si nos posicionamos en la posición del 1 y lo reemplazamos con 30 el 0 sobrescribe al '\n' recordar que es un solo byte aunque su representación en c sea de 2 bytes, en el archivo solo es un byte. y si perdemos ese "enter" la base de datos se corromperia en esa sección.

Lo ideal es escribir todo de nuevo pero si comentas que es de un  GB pues menudo lio.

En dado caso podríamos guardar la parte del Entero en formato binario y leer los 4 u 8 bytes que necesites directo a un entero.

El problema ahi seria que necesitaremos leer la base de datos de otra manera
#1628
Una vez que encuentras tu y editas en memoria lo mas rápido seria volver a escribir todo el archivo, no es lo mas eficiente, si lo que vas a escribir tiene el mismo tamaño que el anterior podrías colocarte en la posición adecuada mediante seek y escribir con fprintf o fwrite segun creas conveniente.

Ahorita te ayudo con la funcion que lo haga.
#1629
Concuerdo con Geeke, de hecho que bueno que lo menciona, mi código actual es este:

char *concat(char *s,...) {
va_list args;
char *buffer;
buffer = calloc(strlen(s)*1000,sizeof(char));
va_start(args, s);
vsprintf(buffer,s, args);
va_end(args);
return buffer;
}


Lo voy a cambiar por:

char *concat(char *s,...) {
va_list args;
unsigned int l;
char *buffer;
l = strlen(s)*1000;
buffer = calloc(l,sizeof(char));
va_start(args, s);
vsprintf(buffer,l,s, args);
va_end(args);
return buffer;
}
#1630
sscanf es para separar la cadena de acuardo a un formato dado y almacenar dichos datos en variables individuales.

La funcion que comento usa snprintf  o vsprintf que es lo opuesto toma variables indivuduales y las junta en una sola cadena de acuerdo a u  formato dado. Yo lo uso en una funcion aparte para que la funcion se encarge de reservar memoria acorde a los parametros dados...