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

 

 


Tema destacado: Únete al Grupo Steam elhacker.NET


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  [Ayuda] Reemplazar String en un archivo
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: [Ayuda] Reemplazar String en un archivo  (Leído 7,920 veces)
.:UND3R:.
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.118


Ingeniería inversa / MASM


Ver Perfil WWW
[Ayuda] Reemplazar String en un archivo
« en: 4 Mayo 2016, 17:35 pm »

Hola a todos, tengo el siguiente archivo llamado BD:

Código:
e97fxosm1h65taazis3p7mktirczgnciie3zk94cwyhwytdsnh*81
aac3liukb2nk4czkgyw90xfmyc6x*96
3b0ziwq1tsgozcrac85o*31
lbn2i7bpvsw6zr6zp75yxfzbpn3nukx8z9en545*1

La idea es crear un programa que busque en base a una substring la línea correcta, una vez encontrada la línea, se debe reemplazar lo que está en la parte derecha del *, esta parte la tengo lista, el problema que tengo en este momento es que una vez teniendo la string original y la nueva string, no sé como sobre-escribir en BD para que esto ocurra, cómo podría hacerlo? Me gustaría poder hacerlo al final de la función seleccionarProducto(), por favor leer el comentario ACAA!

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <assert.h>
  5.  
  6. char resultados[200][300];
  7. char nueva_linea[300];
  8. int opcion;
  9.  
  10. // fuente: http://stackoverflow.com/questions/9210528/split-string-with-delimiters-in-c
  11. char** str_split(char* a_str, const char a_delim){
  12.    char** result    = 0;
  13.    size_t count     = 0;
  14.    char* tmp        = a_str;
  15.    char* last_comma = 0;
  16.    char delim[2];
  17.    delim[0] = a_delim;
  18.    delim[1] = 0;
  19.  
  20.    /* Count how many elements will be extracted. */
  21.    while (*tmp)
  22.    {
  23.        if (a_delim == *tmp)
  24.        {
  25.            count++;
  26.            last_comma = tmp;
  27.        }
  28.        tmp++;
  29.    }
  30.  
  31.    /* Add space for trailing token. */
  32.    count += last_comma < (a_str + strlen(a_str) - 1);
  33.  
  34.    /* Add space for terminating null string so caller
  35.        knows where the list of returned strings ends. */
  36.    count++;
  37.  
  38.    result = malloc(sizeof(char*) * count);
  39.  
  40.    if (result)
  41.    {
  42.        size_t idx  = 0;
  43.        char* token = strtok(a_str, delim);
  44.  
  45.        while (token)
  46.        {
  47.            assert(idx < count);
  48.            *(result + idx++) = strdup(token);
  49.            token = strtok(0, delim);
  50.        }
  51.        assert(idx == count - 1);
  52.        *(result + idx) = 0;
  53.    }
  54.  
  55.    return result;
  56. }
  57.  
  58. void seleccionarProducto(){
  59. int nuevo_stock;
  60. char nuevo_stock_char[3];
  61. char** resultado_split;
  62.  
  63. scanf("%i", &opcion);
  64.  
  65. printf("%s", resultados[opcion-1]);
  66.  
  67. resultado_split = str_split(resultados[opcion-1], '*');
  68.  
  69. printf("\nEl stock actual del producto es: %sPor favor introduzca el nuevo stock:", resultado_split[1]);
  70.  
  71. scanf("%i", &nuevo_stock);
  72. sprintf(nuevo_stock_char, "%d", nuevo_stock); // transforma el nuevo_stock (int) a nuevo_stock_char (char)
  73.  
  74. strcpy(nueva_linea, resultado_split[0]);
  75. strcat(nueva_linea, "*");
  76. strcat(nueva_linea, nuevo_stock_char);
  77.  
  78. free(resultado_split); // libera memoria, pues ya no es necesario split.
  79.  
  80. printf("%s", nueva_linea); // ACAA!! nueva_linea es la que debe reemplazar a resultados[opcion-1] dentro de BD
  81. }
  82.  
  83. void mostrarProducto(int count){
  84. int i;
  85.  
  86. printf("%i coincidencias encontradas...\n\n", count);
  87.  
  88. for(i = 0; i < count; i++){
  89. printf("%i) %s\n", i+1, resultados[i]);
  90. }
  91.  
  92. printf("Por favor, seleccione una opcion: ");
  93. }
  94.  
  95. void buscarProducto(char * codProducto){
  96. FILE * fp;
  97.    char * line = NULL;
  98.    size_t len = 0;
  99.    ssize_t read;
  100. int count = 0;
  101.  
  102. fp = fopen("bd", "r");
  103.    if (fp == NULL)
  104.        exit(EXIT_FAILURE);
  105.  
  106. while((read = getline(&line, &len, fp)) != -1){
  107. if(strstr(line, codProducto) != NULL){
  108. strcpy(resultados[count], line);
  109. count++;
  110.  
  111. if(count > 199) // evita overflow
  112. break;
  113. }
  114.    }
  115.  
  116. if(count != 0){
  117. mostrarProducto(count);
  118. seleccionarProducto();
  119. }else{
  120. printf("No se ha encontrado el producto!");
  121. }
  122.  
  123. fclose(fp);
  124.    if(line)
  125. free(line);
  126.  
  127. //if(count != 0){
  128. // printf("ahora edito");
  129. //}
  130.    exit(EXIT_SUCCESS);
  131. }
  132.  
  133. int main(){
  134. buscarProducto("atud");
  135. exit(EXIT_SUCCESS);
  136. }

Muchas gracias y espero su ayuda, saludos  ;-)


En línea


Solicitudes de crack, keygen, serial solo a través de mensajes privados (PM)
AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.705


🏴 Libertad!!!!!


Ver Perfil WWW
Re: [Ayuda] Reemplazar String en un archivo
« Respuesta #1 en: 4 Mayo 2016, 18:05 pm »

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.


En línea

.:UND3R:.
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.118


Ingeniería inversa / MASM


Ver Perfil WWW
Re: [Ayuda] Reemplazar String en un archivo
« Respuesta #2 en: 4 Mayo 2016, 18:16 pm »

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.

Muchísimas gracias AlbertoBSD, sería ideal lo de reemplazar en la posición, ahora mi pregunta es si por ejemplo tenemos
Citar
abcd*1\n
efgh*12\n

si reemplazo la 1era linea con 30 por ejemplo, esto no afectaría el resto?
Citar
abcd*30n
efgh*12\n

Si te fijas se perdería el \, por lo cual si es el caso, mejor descartarlo. Mi idea sería una vez cerrado el archivo DB, sería abrirlo de nuevo e ir línea por línea buscando resultados[opcion-1] y si se encuentra, se reemplace por nueva_linea y que luego salga

es una simple idea.

PD: Esta tarea tiene como finalidad probar el los recursos del sistema, etc. por lo cual BD enrealidad será de 1 GB y además los caracteres serán valores alfanuméricos de rango 250-300 de largo
En línea


Solicitudes de crack, keygen, serial solo a través de mensajes privados (PM)
AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.705


🏴 Libertad!!!!!


Ver Perfil WWW
Re: [Ayuda] Reemplazar String en un archivo
« Respuesta #3 en: 4 Mayo 2016, 18:29 pm »

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
« Última modificación: 4 Mayo 2016, 18:34 pm por AlbertoBSD » En línea

class_OpenGL


Desconectado Desconectado

Mensajes: 437

Si usas Direct3D, no eres mi amigo :P


Ver Perfil
Re: [Ayuda] Reemplazar String en un archivo
« Respuesta #4 en: 4 Mayo 2016, 18:33 pm »

Como mucho, si solo vas a reemplazar una linea de un archivo muy grande, creo que lo más eficiente sería leer el archivo desde la posición que quieres reemplazar, guardarlo todo en un búfer, sobreescribir desde la posición a reemplazar, y volver a escribir todo el búfer con fwrite... No se me ocurre nada más D:



Creo que si el archivo es demasiado grande para la RAM, se podría hacer esto:
* Obtenemos la cadena del archivo desde la posición que quieras con longitud de la nueva cadena con, por ejemplo, fread.
* Reemplazamos desde la posición deseada con la cadena con, por ejemplo, fwrite.
* Obtenemos la siguiente cadena desde la posición original con un desplazamiento (offset) de la longitud de la cadena que has reemplazado antes. Es fácil pues la función seek permite poner desplazamientos.
* Reemplazamos la cadena que acabamos de leer con la cadena que obtuvimos antes del archivo con, por ejemplo, fread
* Hacemos esto hasta que hayamos llegado al final del archivo
« Última modificación: 5 Mayo 2016, 01:50 am por Eternal Idol » En línea

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL
.:UND3R:.
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.118


Ingeniería inversa / MASM


Ver Perfil WWW
Re: [Ayuda] Reemplazar String en un archivo
« Respuesta #5 en: 4 Mayo 2016, 18:54 pm »

Creo que si el archivo es demasiado grande para la RAM, se podría hacer esto:
* Obtenemos la cadena del archivo desde la posición que quieras con longitud de la nueva cadena con, por ejemplo, fread.
* Reemplazamos desde la posición deseada con la cadena con, por ejemplo, fwrite.
* Obtenemos la siguiente cadena desde la posición original con un desplazamiento (offset) de la longitud de la cadena que has reemplazado antes. Es fácil pues la función seek permite poner desplazamientos.
* Reemplazamos la cadena que acabamos de leer con la cadena que obtuvimos antes del archivo con, por ejemplo, fread
* Hacemos esto hasta que hayamos llegado al final del archivo

Me parece una excelente idea, que opinas AlbertoBSD?

Cabe destacar que claro será un archivo grande pero no descomunal, la idea es que este proceso se demore aprox 10 minutos, por lo cual es cosa de ir jugando con la cantidad de datos de la BD por lo cual la eficiencia acá no aplica mucho.

¿Cómo podría hacer lo que me comentas? disculpa pero conozco C pero hasta un cierto punto, saludos y gracias a ambos por su gran interés en querer ayudar :)
En línea


Solicitudes de crack, keygen, serial solo a través de mensajes privados (PM)
AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.705


🏴 Libertad!!!!!


Ver Perfil WWW
Re: [Ayuda] Reemplazar String en un archivo
« Respuesta #6 en: 4 Mayo 2016, 19:08 pm »

A ver implemente una forma de reescribir todo el archivo, me tome de la liberar de cambiar algunas cosas..

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <assert.h>
  5. #include<sys/stat.h>
  6.  
  7. char **resultados;
  8. char **lines;
  9. char *nueva_linea;
  10. int *map;
  11.  
  12. int count = 0;
  13.  
  14. char** str_split(char* a_str, const char a_delim){
  15.    char** result    = 0;
  16.    size_t count     = 0;
  17.    char* tmp        = a_str;
  18.    char* last_comma = 0;
  19.    char delim[2];
  20.    delim[0] = a_delim;
  21.    delim[1] = 0;
  22.    while (*tmp)
  23.    {
  24.        if (a_delim == *tmp)
  25.        {
  26.            count++;
  27.            last_comma = tmp;
  28.        }
  29.        tmp++;
  30.    }
  31.    count += last_comma < (a_str + strlen(a_str) - 1);
  32.    count++;
  33.    result = malloc(sizeof(char*) * count);
  34.    if (result)
  35.    {
  36.        size_t idx  = 0;
  37.        char* token = strtok(a_str, delim);
  38.        while (token)
  39.        {
  40.            assert(idx < count);
  41.            *(result + idx++) = strdup(token);
  42.            token = strtok(0, delim);
  43.        }
  44.        assert(idx == count - 1);
  45.        *(result + idx) = 0;
  46.    }
  47.    return result;
  48. }
  49.  
  50. off_t fsize(char *filename) {
  51. struct stat st;
  52. if (stat(filename, &st) == 0)
  53. return st.st_size;
  54. return -1;
  55. }
  56.  
  57. void mostrarProducto(){
  58. int i;
  59. printf("%i coincidencias encontradas...\n\n", count);
  60. for(i = 0; i < count; i++){
  61. printf("%i) %s\n", i+1, resultados[i]);
  62. }
  63. printf("Por favor, seleccione una opcion: ");
  64. }
  65.  
  66. void seleccionarProducto(){
  67. int nuevo_stock,opcion;
  68.  
  69. char** resultado_split;
  70. scanf("%i", &opcion);
  71. printf("%s", resultados[opcion-1]);
  72.  
  73. resultado_split = str_split(resultados[opcion-1], '*');
  74.  
  75. printf("\nEl stock actual del producto es: %s\nPor favor introduzca el nuevo stock:",resultado_split[1]);
  76. scanf("%i", &nuevo_stock);
  77. nueva_linea = calloc(20+strlen(resultado_split[0]),1);
  78. sprintf(nueva_linea,"%s*%i",resultado_split[0],nuevo_stock);
  79. free(resultado_split[2]);
  80. free(resultado_split[1]);
  81. free(resultado_split);
  82. printf("%s", nueva_linea); // ACAA!! nueva_linea es la que debe reemplazar a
  83. free(lines[map[opcion-1]]);
  84. lines[map[opcion-1]] = nueva_linea;
  85. }
  86.  
  87. void buscarProducto(char * codProducto){
  88. FILE * fp;
  89. char *file_buff;
  90.    size_t len = 0;
  91. int i = 0, j = 0;
  92. len = fsize("bd");
  93. file_buff =  calloc(len+1,sizeof(char));
  94. fp = fopen("bd", "r");
  95.    if (fp == NULL)
  96.        exit(EXIT_FAILURE);
  97.  
  98. fread(file_buff,sizeof(char),len,fp);
  99. fclose(fp);
  100. lines = str_split(file_buff,'\n');
  101. memset(file_buff,0,len);
  102. free(file_buff);
  103. while(lines[i] != NULL) {
  104. printf("Examinando linea %i: %s\n",i,lines[i]);
  105. if(strstr(lines[i],codProducto) != NULL) {
  106. printf("Coinciendia %s encontrada en linea %i, copiando apuntador a resultado %i\n",codProducto,i,count);
  107. resultados = realloc(resultados,sizeof(char*)*count+1);
  108. map = realloc(map,sizeof(int)*count+1);
  109. resultados[count] = lines[i];
  110. map[count] = i;
  111. count++;
  112. }
  113. i++;
  114. }
  115. if(count != 0){
  116. mostrarProducto(count);
  117. seleccionarProducto();
  118. }else{
  119. printf("No se ha encontrado el producto!");
  120. }
  121. j = 0;
  122. fp = fopen("bd","w");
  123. while(j < i) {
  124. fprintf(fp,"%s\n",lines[j]);
  125. free(lines[j]);
  126. j++;
  127. }
  128. fclose(fp);
  129.    exit(EXIT_SUCCESS);
  130. }
  131.  
  132.  
  133. int main(){
  134. buscarProducto("h65t");
  135. exit(EXIT_SUCCESS);
  136. }


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

« Última modificación: 4 Mayo 2016, 19:39 pm por AlbertoBSD » En línea

.:UND3R:.
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.118


Ingeniería inversa / MASM


Ver Perfil WWW
Re: [Ayuda] Reemplazar String en un archivo
« Respuesta #7 en: 4 Mayo 2016, 19:12 pm »

 :o cada vez lo veo más chino, eso ocurre cuando te acostumbras a programar para la universidad/facultad, si necesitas que haga algo, por favor dime, saludos.

PD: Estoy ansioso jaja
En línea


Solicitudes de crack, keygen, serial solo a través de mensajes privados (PM)
AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.705


🏴 Libertad!!!!!


Ver Perfil WWW
Re: [Ayuda] Reemplazar String en un archivo
« Respuesta #8 en: 4 Mayo 2016, 19:45 pm »

Ya esta terminado estaba modificando la variable resultados y no la de lineas

La opciones fue guardar las lineas del archivo en un arragle

Código:
char **lines;

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

Código
  1. printf("%s", nueva_linea); // ACAA!! nueva_linea es la que debe reemplazar a
  2. free(lines[map[opcion-1]]);
  3. lines[map[opcion-1]] = nueva_linea;
  4.  

Posteriormente escribir el archivo de nuevo

Código
  1. fp = fopen("bd","w");
  2. while(j < i) {
  3. fprintf(fp,"%s\n",lines[j]);
  4. free(lines[j]);
  5. j++;
  6. }
  7. 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

Código:
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.
« Última modificación: 4 Mayo 2016, 19:51 pm por AlbertoBSD » En línea

class_OpenGL


Desconectado Desconectado

Mensajes: 437

Si usas Direct3D, no eres mi amigo :P


Ver Perfil
Re: [Ayuda] Reemplazar String en un archivo
« Respuesta #9 en: 4 Mayo 2016, 19:49 pm »

Yo tampoco sé mucho sobre C, también estoy aprendiendo xD.

Creo que una forma fácil de implementar este algoritmo sería:
Código
  1. void insertar(FILE * archivo, unsigned int pos, const char *nueva_cadena, unsigned int longitud_cadena) {
  2.    char *buffer = malloc(longitud_cadena);
  3.  
  4.    fseek(archivo, pos, SEEK_CUR); // Nos movemos por el archivo hasta la posición 'pos'
  5.    fread((void *)buffer, sizeof(char), longitud_cadena, archivo);
  6.    clearerr(archivo); // Por si hemos llegado al final del archivo...
  7.    fseek(archivo, pos, SEEK_CUR);
  8.    fwrite((const void *)nueva_cadena, sizeof(char), longitud_cadena, archivo);
  9.  
  10.    if(feof(archivo) != 0)
  11.        insertar(archivo, pos+longitud_cadena, buffer, longitud_cadena);
  12.  
  13.    free(buffer);
  14. }

¡OJO! El código no lo he probado. Si alguien ve algun error (lo cual es muy posible), por favor, avise
En línea

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL
Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
[DUda] Reemplazar un archivo por otro en vB
Programación Visual Basic
NsTeam 1 2,087 Último mensaje 10 Diciembre 2009, 20:52 pm
por NsTeam
ayuda con batch, modificar un archivo sin reemplazar lo anterior.
Scripting
kapototal1 2 2,825 Último mensaje 23 Noviembre 2010, 04:17 am
por kapototal1
problemas al intentar reemplazar string en la memoria. « 1 2 »
Programación C/C++
Destro- 11 5,466 Último mensaje 29 Noviembre 2011, 08:59 am
por Eternal Idol
Reemplazar archivo en cache
Hacking
Topixx 0 1,944 Último mensaje 24 Septiembre 2012, 10:34 am
por Topixx
Buscar y reemplazar palabra en archivo
Programación C/C++
fran7385 3 5,005 Último mensaje 28 Enero 2014, 22:47 pm
por ivancea96
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines