Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Problema al leer archivo

Estas en el tema de Problema al leer archivo en el foro de C/C++ en Foros del Web. Buenas a todos, estoy tratando de leer un archivo, y hacer que cada línea del archivo se guarde en un arreglo que es de un ...
  #1 (permalink)  
Antiguo 15/04/2016, 19:13
Avatar de princk093  
Fecha de Ingreso: febrero-2015
Ubicación: Venezuela
Mensajes: 28
Antigüedad: 9 años, 9 meses
Puntos: 7
Problema al leer archivo

Buenas a todos, estoy tratando de leer un archivo, y hacer que cada línea del archivo se guarde en un arreglo que es de un tipo estructura que dentro contiene un char *string.

El archivo tiene el siguiente contenido:
Cita:
44900388_expediente_Brayan Narvaez_28/10/96_20_0_1_
22907088_expediente_Brayan Dos_29/11/97_12_0_1_
81800198_expediente_Csn Tres_29/11/97_12_0_1_
81800198xx_expediente_Csn Tres_29/11/97_12_0_1_
Código:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define true 1
#define false 0

typedef struct {
  char *str;
} array_s;

array_s *OpFile(char *route) {
  FILE * f = fopen(route,"r");
  array_s *vector = (array_s *) malloc(1);
  if(f != NULL ) {
    static char tmp[180];
    unsigned int bytes = 0, x = 0;
    while (0 == feof(f)) {
      bytes = bytes + sizeof(array_s);
      vector = (array_s *) realloc(vector,bytes);
      fgets(tmp,180,f);
      vector[x].str = tmp;
      x++;
    }
    vector[x - 1].str = "END";
  } else {
    free(vector);
    printf("ERROR: Abriendo archivo %s\n",route);
    exit(false);
  }
  fclose(f);

  printf("%s\n",vector[0].str);
  printf("%s\n",vector[1].str);
  printf("%s\n",vector[2].str);
  printf("%s\n",vector[3].str);
  printf("%s\n",vector[4].str);
  
  /*
    LA SALIDA DE ESOS PRINTF IMPRIME:
    81800198xx_expediente_Csn Tres_29/11/97_12_0_1_
    81800198xx_expediente_Csn Tres_29/11/97_12_0_1_
    81800198xx_expediente_Csn Tres_29/11/97_12_0_1_
    81800198xx_expediente_Csn Tres_29/11/97_12_0_1_
    END
    
    END se genera aqui  vector[x - 1].str = "END";
    y los demas en vector[x].str = tmp
    ¿Por qué siempre me sale el último y no salen los demás en el orden que los inserté?
    
  */

  return vector;
}

int main() {

array_s *v = OpFile("alumnos.txt");

}
  #2 (permalink)  
Antiguo 16/04/2016, 03:59
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 9 meses
Puntos: 3
Respuesta: Problema al leer archivo

Eso crashea seguro.
1. str es un puntero y no tiene memoria asignada con lo que puede apuntar a cualquier sitio. O lo cambias por un char [] con tamaño fijo o tmp tienes que asignarle memoria dinámica con malloc. Dependiendo de lo que decidas tmp será útil o sobrará.
2. ¿Liberas la memoria si falla al obtenerla? No se que hará free (NULL) pero no creo que sea buena idea. Y si obtienes la memoria necesaria sales sin liberarla.
3. vector[x - 1].str = "END"; ¿que pasara si el archivo estuviese vacío? Pues que x-1 = -1 y te saldrías del rango. Y además a un array de caracteres no puedes asignarle así una cadena,tienes que usar strcpy o similares.
4. Esta linea:
Código C++:
Ver original
  1. vector = (array_s *) realloc(vector,bytes);
Es lo mismo que:
Código C++:
Ver original
  1. vector = (array_s *) realloc(vector,sizeof (array_s));
Y te ahorras una variable.
5. ¿para que necesitas que tmp sea estática? Eso sobra.
Por cierto no necesitas para nada que el tipo array_s sea una estructura ya que solo tiene un miembro. Para tu caso te valdria algo así y seria más sencillo.
Código C++:
Ver original
  1. typedef char str [128];
  2. str *lista=(str*)malloc (sizeof (str));
Ahora en lista [0] ya podrías guardar una cadena con la ayuda de fgets.
Código C++:
Ver original
  1. fgets(&lista [0], sizeof (str),fichero);
Y ya puestos no estaría mal que la función en vez de retornar el puntero al tipo retorne el número de líneas copiadas y el tipo lo pasases como parámetro. Si lo haces así yo crearía una función que cuente el número de líneas del archivo y con ese valor ya sabre cuanta memoria necesito con lo que me ahorro llamar a realloc en tu función. Seria algo asi:
Código C++:
Ver original
  1. int nlineas=ContarLineas ("fichero.txt");
  2. if (nlineas >0){
  3.    str *lineas=(str*)malloc (sizeof (str)*nlineas);
  4.    if (líneas !=NULL){
  5.       int nelementos=OpFile ("fichero.txt",lineas);
  6.       if (nelementos == nlineas){
  7.          //si coinciden es que todo fue bien
  8.          //haces lo que desees con las cadenas
  9.       }else {
  10.          // hubo algún error al copiar las líneas así que liberamos y salimos
  11.       }
  12.       free (lineas);
  13.    }
  14. }
Con eso ya tienes para entretenerte.

Última edición por aguml; 16/04/2016 a las 04:32

Etiquetas: char, int, string, vector
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:33.