C ++ reads files sometimes

1

I am having problems with a program in which I must generate a matrix (board) with files, the problem is that I can not read the files only from time to time.

the code to read the matrix and save it is as follows:

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;
            }
        }
    }
}

I just use cout to know where I'm having the error since I'm using Qt and I can not use the debug option.

In a normal situation this exit gives:

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_||___|

but after a while playing gives this other way out:

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_||___||___||___|



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



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

I've been with this problem for about a month, believing that I was in the stoi, then I realized that I was not reading any data, so stoi threw me the prorama, recently I put a try and catch and saw that there was no problem there, then add the if (fp! = NULL) and it was where it detected that the file was not opening.

I hope you can help me, because I do not understand why you only open it sometimes, things do not change, and I have not done strange things like deleting files while running the program or things like that.

    
asked by Dykeiichi 14.04.2018 в 03:05
source

1 answer

1

I bet that "after a while playing" is when you call leerTablero for the second time. You are opening several files but you never close them, since the closing operation is done on NULL not on the handle active:

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

The surprising thing is that it works for you, some implementation of fclose could fail to try to operate on NULL .

Other things to consider.

You are programming in C ++ not in C, so use the C ++ utilities:

  • std::ifstream instead of FILE * .
  • std::string instead of arrays of characters such as char ruta[30]
  • std::ifstream::get instead of fgetc

Also keep in mind:

Proposal.

Taking into account the proposed changes, your code could look like this:

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";
            }
        }
    }
}

This code surely solves your problem with the files, since std::ifstream automatically closes the open file when it leaves scope, as it follows the RAII design pattern .

Additionally an alias has been used to refer to the type of the parameter, improving the expressiveness of the code and allowing not losing size information when passing the parameter (now by reference, instead of by pointer).

Finally the expression matriz[j][i] = 0; has been moved to the beginning of the double reading loop of rows and columns since the normal behavior will overwrite the value and the erroneous behavior will leave it intact.

You were not using the ruta fix for anything useful, dispense with it; besides saving you all the code to fill it, you save time of process.

    
answered by 16.04.2018 / 09:28
source