1

estoy teniendo problemas con un programa en el que debo generar una matriz (tablero) con archivos, el problema es que no puedo leer los archivos solo de vez en cuando.

el codigo para leer la matriz y guardarla es el siguiente:

void G2048::leerTablero(int matriz[][4]){
    cout<<"Inicia metodo leer tablero"<<endl;
    for(int i = 0; i<4 ; i++){
        for(int j = 0; j<4 ; j++){
            cout<<"Leyendo j="<<j<<" i="<<i<<endl;
            char ruta[30] = "                             ";

            string path;
            path = "c:/2048/tablero/" + to_string(j) + to_string(i) + ".gtab";
            cout<<"path: "<<path<<endl;
            string snumber = "";
            strcpy(ruta,path.c_str());
            cout<<"ruta: "<<ruta<<endl;

            FILE *fpleer;
            fpleer = fopen(ruta, "r");
            char caracter;
            if (fpleer != NULL){
                while((caracter = fgetc(fpleer)) != EOF){
                    snumber = snumber + caracter;
                }
                fpleer = NULL;
                fclose (fpleer);
                try{
                    matriz[j][i]  = stoi(snumber);
                }catch(...){
                    matriz[j][i]  = 0;
                }
            }else{
                matriz[j][i]  = 0;
                cout<<"No se leyo el archivo"<<endl;
            }
        }
    }
}

los cout solo los utilizo para saber donde estoy teniendo el error ya que estoy utilizando Qt y no puedo usar la opcion de debug.

En una situacion normal da esta salida:

Inicia metodo leer tablero

Leyendo i=0 j=0

path: c:/2048/tablero/00.gtab

ruta: c:/2048/tablero/00.gtab

H2Hc:/2048/tablero/00.gtab

I2I

Leyendo i=0 j=1

path: c:/2048/tablero/10.gtab

ruta: c:/2048/tablero/10.gtab

H0Hc:/2048/tablero/10.gtab

I0I

Leyendo i=0 j=2

path: c:/2048/tablero/20.gtab

ruta: c:/2048/tablero/20.gtab

H0Hc:/2048/tablero/20.gtab

I0I

Leyendo i=0 j=3

path: c:/2048/tablero/30.gtab

ruta: c:/2048/tablero/30.gtab

H2Hc:/2048/tablero/30.gtab

I2I

Leyendo i=1 j=0

path: c:/2048/tablero/01.gtab

ruta: c:/2048/tablero/01.gtab

H0Hc:/2048/tablero/01.gtab

I0I

Leyendo i=1 j=1

path: c:/2048/tablero/11.gtab

ruta: c:/2048/tablero/11.gtab

H0Hc:/2048/tablero/11.gtab

I0I

Leyendo i=1 j=2

path: c:/2048/tablero/21.gtab

ruta: c:/2048/tablero/21.gtab

H0Hc:/2048/tablero/21.gtab

I0I

Leyendo i=1 j=3

path: c:/2048/tablero/31.gtab

ruta: c:/2048/tablero/31.gtab

H0Hc:/2048/tablero/31.gtab

I0I

Leyendo i=2 j=0

path: c:/2048/tablero/02.gtab

ruta: c:/2048/tablero/02.gtab

H8Hc:/2048/tablero/02.gtab

I8I

Leyendo i=2 j=1

path: c:/2048/tablero/12.gtab

ruta: c:/2048/tablero/12.gtab

H4Hc:/2048/tablero/12.gtab

I4I

Leyendo i=2 j=2

path: c:/2048/tablero/22.gtab

ruta: c:/2048/tablero/22.gtab

H2Hc:/2048/tablero/22.gtab

I2I

Leyendo i=2 j=3

path: c:/2048/tablero/32.gtab

ruta: c:/2048/tablero/32.gtab

H0Hc:/2048/tablero/32.gtab

I0I

Leyendo i=3 j=0

path: c:/2048/tablero/03.gtab

ruta: c:/2048/tablero/03.gtab

H8Hc:/2048/tablero/03.gtab

I8I

Leyendo i=3 j=1

path: c:/2048/tablero/13.gtab

ruta: c:/2048/tablero/13.gtab

H4Hc:/2048/tablero/13.gtab

I4I

Leyendo i=3 j=2

path: c:/2048/tablero/23.gtab

ruta: c:/2048/tablero/23.gtab

H2Hc:/2048/tablero/23.gtab

I2I

Leyendo i=3 j=3

path: c:/2048/tablero/33.gtab

ruta: c:/2048/tablero/33.gtab

H0Hc:/2048/tablero/33.gtab

I0I

|_4_||___||___||_2_|



|___||___||___||___|



|_8_||_4_||_2_||___|



|_8_||_4_||_2_||___|

pero despues de un rato jugando da esta otra salida:

Inicia metodo leer tablero

Leyendo i=0 j=0

path: c:/2048/tablero/00.gtab

ruta: c:/2048/tablero/00.gtab

No se leyo el archivo

Leyendo i=0 j=1

path: c:/2048/tablero/10.gtab

ruta: c:/2048/tablero/10.gtab

No se leyo el archivo

Leyendo i=0 j=2

path: c:/2048/tablero/20.gtab

ruta: c:/2048/tablero/20.gtab

No se leyo el archivo

Leyendo i=0 j=3

path: c:/2048/tablero/30.gtab

ruta: c:/2048/tablero/30.gtab

No se leyo el archivo

Leyendo i=1 j=0

path: c:/2048/tablero/01.gtab

ruta: c:/2048/tablero/01.gtab

No se leyo el archivo

Leyendo i=1 j=1

path: c:/2048/tablero/11.gtab

ruta: c:/2048/tablero/11.gtab

No se leyo el archivo

Leyendo i=1 j=2

path: c:/2048/tablero/21.gtab

ruta: c:/2048/tablero/21.gtab

No se leyo el archivo

Leyendo i=1 j=3

path: c:/2048/tablero/31.gtab

ruta: c:/2048/tablero/31.gtab

No se leyo el archivo

Leyendo i=2 j=0

path: c:/2048/tablero/02.gtab

ruta: c:/2048/tablero/02.gtab

No se leyo el archivo

Leyendo i=2 j=1

path: c:/2048/tablero/12.gtab

ruta: c:/2048/tablero/12.gtab

No se leyo el archivo

Leyendo i=2 j=2

path: c:/2048/tablero/22.gtab

ruta: c:/2048/tablero/22.gtab

No se leyo el archivo

Leyendo i=2 j=3

path: c:/2048/tablero/32.gtab

ruta: c:/2048/tablero/32.gtab

No se leyo el archivo

Leyendo i=3 j=0

path: c:/2048/tablero/03.gtab

ruta: c:/2048/tablero/03.gtab

No se leyo el archivo

Leyendo i=3 j=1

path: c:/2048/tablero/13.gtab

ruta: c:/2048/tablero/13.gtab

No se leyo el archivo

Leyendo i=3 j=2

path: c:/2048/tablero/23.gtab

ruta: c:/2048/tablero/23.gtab

No se leyo el archivo

Leyendo i=3 j=3

path: c:/2048/tablero/33.gtab

ruta: c:/2048/tablero/33.gtab

No se leyo el archivo

Inicia metodo leer tablero

Leyendo i=0 j=0

path: c:/2048/tablero/00.gtab

ruta: c:/2048/tablero/00.gtab

No se leyo el archivo

Leyendo i=0 j=1

path: c:/2048/tablero/10.gtab

ruta: c:/2048/tablero/10.gtab

No se leyo el archivo

Leyendo i=0 j=2

path: c:/2048/tablero/20.gtab

ruta: c:/2048/tablero/20.gtab

No se leyo el archivo

Leyendo i=0 j=3

path: c:/2048/tablero/30.gtab

ruta: c:/2048/tablero/30.gtab

No se leyo el archivo

Leyendo i=1 j=0

path: c:/2048/tablero/01.gtab

ruta: c:/2048/tablero/01.gtab

No se leyo el archivo

Leyendo i=1 j=1

path: c:/2048/tablero/11.gtab

ruta: c:/2048/tablero/11.gtab

No se leyo el archivo

Leyendo i=1 j=2

path: c:/2048/tablero/21.gtab

ruta: c:/2048/tablero/21.gtab

No se leyo el archivo

Leyendo i=1 j=3

path: c:/2048/tablero/31.gtab

ruta: c:/2048/tablero/31.gtab

No se leyo el archivo

Leyendo i=2 j=0

path: c:/2048/tablero/02.gtab

ruta: c:/2048/tablero/02.gtab

No se leyo el archivo

Leyendo i=2 j=1

path: c:/2048/tablero/12.gtab

ruta: c:/2048/tablero/12.gtab

No se leyo el archivo

Leyendo i=2 j=2

path: c:/2048/tablero/22.gtab

ruta: c:/2048/tablero/22.gtab

No se leyo el archivo

Leyendo i=2 j=3

path: c:/2048/tablero/32.gtab

ruta: c:/2048/tablero/32.gtab

No se leyo el archivo

Leyendo i=3 j=0

path: c:/2048/tablero/03.gtab

ruta: c:/2048/tablero/03.gtab

No se leyo el archivo

Leyendo i=3 j=1

path: c:/2048/tablero/13.gtab

ruta: c:/2048/tablero/13.gtab

No se leyo el archivo

Leyendo i=3 j=2

path: c:/2048/tablero/23.gtab

ruta: c:/2048/tablero/23.gtab

No se leyo el archivo

Leyendo i=3 j=3

path: c:/2048/tablero/33.gtab

ruta: c:/2048/tablero/33.gtab

No se leyo el archivo

|___||___||___||___|



|_2_||___||___||___|



|___||___||___||___|



|___||___||___||___|

Llevo aproximadamente un mes con este problema, crellendo que estaba en el stoi, luego me di cuenta que no estaba leyendo ningun dato, por lo que stoi me tiraba el prorama, hace poco puse un try y catch y vi que no habia problema ahi, despues agregue el if (fp != NULL) y fue donde detecte que el archivo no se estaba abriendo.

Espero me puedan ayudar, ya que no entiendo por que solo lo abre a veces, las cosas no cambian, y no he hecho cosas raras como borrar archivos mientras corre el programa o cosas asi.

Dykeiichi
  • 15
  • 3
  • Estas leyendo el archivo al estilo de C, C++ ofrece métodos mas sencillos. –  Apr 14 '18 at 03:34
  • Tu problema es dificil, yo diria imposible, de resolver. Te recomiendo centrarte en el problema principal y no tanto en tu solucion. Por ejemplo muestra un ejemplo del archivo que estas leyendo, cada cuanto tiempo lo tienes que leer, y que tipo de datos extraes del archivo. –  Apr 14 '18 at 03:36
  • Yo pienso que el problema esta en las siguientes instrucciones: `fpleer = NULL; fclose (fpleer);`, debe ser al reves, primero cierras el archivo y despues estableces a nulo el puntero –  Apr 14 '18 at 03:39

1 Answers1

1

Apuesto a que "después de un rato jugando" es al llamar por segunda vez a leerTablero. Estas abriendo varios archivos pero no los cierras nunca, ya que la operación de cierre la haces sobre NULL no sobre el handle activo:

fpleer = NULL;    // Asigna 'NULL' a fpleer
fclose (fpleer);  // Llama 'fclose' sobre 'NULL'

Lo sorprendente es que te funcione, alguna implementación de fclose podría fallar al intentar operar sobre NULL.

Otras cosas a tener en cuenta.

Estás programando en C++ no en C, así que usa las utilidades de C++:

  • std::ifstream en lugar de FILE *.
  • std::string en lugar de arreglos de caracteres como char ruta[30]
  • std::ifstream::get en lugar de fgetc

También hay que tener en cuenta:

Propuesta.

Teniendo en cuenta los cambios propuestos, tu código podría quedar así:

using matriz4x4 = int[4][4];

void G2048::leerTablero(matriz4x4 &matriz){
    std::cout<<"Inicia metodo leer tablero\n";

    for (int i = 0; i < 4 ; ++i) {
        for (int j = 0; j < 4 ; ++j) {
            matriz[j][i]  = 0;
            std::cout << "Leyendo j=" << j << " i=" << i << '\n';
            std::string path{"c:/2048/tablero/" + std::to_string(j) + std::to_string(i) + ".gtab"};
            std::cout << "path: " << path << '\n';
            std::string snumber{};

            if (std::ifstream leer{path}) {
                char caracter{};
                while(leer.get(caracter)) {
                    snumber.push_back(caracter);
                }

                try {
                    matriz[j][i] = std::stoi(snumber);
                } catch(const std::invalid_argument &ia) {
                    std::cout << ia.what() << '\n';
                } catch(const std::out_of_range &oor) {
                    std::cout << oor.what() << '\n';
                }
            } else {
                cout << "No se leyo el archivo\n";
            }
        }
    }
}

Este código seguramente soluciona tu problema con los archivos, ya que std::ifstream cierra automáticamente el archivo abierto al salir de ámbito ya que sigue el patrón de diseño RAII.

Adicionalmente se ha usado un alias para referirnos al tipo del parámetro, mejorando la expresividad del código y permitiendo no perder información de tamaño al pasar el parámetro (ahora por referencia, en lugar de por puntero).

Por último la expresión matriz[j][i] = 0; se ha movido al inicio del doble bucle de lectura de filas y columnas ya que el comportamiento normal sobre-escribirá el valor y el comportamiento erróneo lo dejará intacto.

No estabas usando el arreglo ruta para nada útil, prescinde de él; además de ahorrarte todo el código de rellenarlo ahorras tiempo de proceso.

PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82
  • Ya quedo solucionado, al parecer mi problema si era que se quedaban abiertos los archivos, no solo en esa parte del codigo, si no que en otras funciones tambien, asi que implementare tambien los cambios que me dices en todo el proyecto, muchas gracias – Dykeiichi Apr 17 '18 at 22:47