-1

I was trying to read a struct from a .text file and then save it in a new text file to see if it worked, but when it's getting saved the infamous error appears "run-time check failure #2 - stack around the variable 'pers' was corrupted". I don't know which size I should give to the struct persona pers in order for it to work. This is the .txt file:

Mirio Togata

18937332

15/7/1951

Shigaraki Tomura

17304739

24/11/1930

And this is the code:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#define LNOM 32
#define TAM 2 /*The size I established for the struct persona is 2 because there are 2 people*/

struct fecha { int d, m, a; };
struct persona
{
  char nombre[LNOM];
  int dni;
  struct fecha nacim;
};

int readText(struct persona l[], int cant)
{
  printf("Leyendo...\n");
  char nom[LNOM];
  FILE *pf = fopen("persona.txt", "r");
  if (pf)
  {
    fgets(nom, LNOM, pf);
    while (!feof(pf))
    {
        strcpy(l[cant].nombre, nom);
        fscanf(pf, "%d", &l[cant].dni);
        fgetc(pf);
        fscanf(pf, "%d/%d/%d", &l[cant].nacim.d, &l[cant].nacim.m, &l[cant].nacim.a);
        fgetc(pf);
        cant++;
        fgets(nom, LNOM, pf);
    }
    fclose(pf);
  }
return cant;
}

void saveText(struct persona l[], int cant)
{
  printf("Grabando...\n");
  int i;
  FILE *pf = fopen("personados.txt", "w");
  if (pf)
  {
    for (i = 0; i < cant; i++)
    {
        fprintf(pf, "%s\n", l[i].nombre);
        fprintf(pf, "%d\n", l[i].dni);
        fprintf(pf, "%d/%d/%d\n", l[i].nacim.d, l[i].nacim.m, l[i].nacim.a);
    }
    fclose(pf);
  }
}

int main(void)
{
  int cant = 0;
  struct persona pers[TAM];
  cant = readText(&pers[TAM],cant);
  saveText(&pers[TAM],cant);
  return 0;
}

Thanks in advance.

Community
  • 1
  • 1
Thomas GM
  • 27
  • 10
  • 1
    Please use *actual* C++ idioms instead of C ones, that although work, are pretty error prone, as you just noticed. – Rakete1111 Sep 24 '17 at 18:36
  • 1
    What do you think this `leerTexto(&pers[TAM]` does? –  Sep 24 '17 at 18:39
  • 2
    `while (!feof(pf))` is a [not so good idea](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong). – user0042 Sep 24 '17 at 18:39

1 Answers1

0

First a refresher of array indexing.

pers[0]

provides the first persona in pers.

pers[1]

would provide the second, and

pers[2]

would be the third. This sequence can go on for quite a while, but because

#define TAM 2

will substitute all TAMs for 2

struct persona pers[TAM];

becomes

struct persona pers[2];

so pers has only two valid entries. This also means

pers[TAM] 

becomes

pers[2] 

which we saw above gets the third element in pers, and we now know there is no third element in pers.

So

cant = readText(&pers[TAM],cant);

Gets the address of the non-existent third element of pers and passes it into into readText as l. Since l is pointing outside the valid range for pers, reading into the element pointed at by l will corrupt the stack and cause the error message.

The solution is to read into a valid element of pers, &pers[0] or &pers[1]. Since two entries will be read from the file by readText, starting with &pers[1] and reading into element 2 and the non existent element 3 is not recommended.

user4581301
  • 33,082
  • 7
  • 33
  • 54
  • Thanks for your help, I wrote _**cant = readText(&pers[0],cant);**_ instead of _**cant = readText(&pers[TAM],cant);**_ and now it works perfectly – Thomas GM Sep 24 '17 at 19:48
  • @Kuroki One minor improvement over that. [An array decays to a pointer](https://stackoverflow.com/questions/1461432/what-is-array-decaying), so you can write `cant = readText(pers,cant);` – user4581301 Sep 24 '17 at 19:58