Question

I have a file named phobebook where i retrieve the number of contacts I have(here the int is assigned on variable cc), then saved the names, address etc. problem is when I display the info, the details are there but they are separated with new lines. I tried to put the \0 but it seems it does not work.

typedef struct myphonebook{
  char name[31];
  char address[101];
  char cellphone[11];
  char email[21];
} Myphonebooktype;

FILE*db;

db = fopen("db.txt", "r");

fscanf(db, "%d" , &cc);

pb = (Myphonebooktype*)malloc(cc*sizeof(Myphonebooktype));
addcounter = cc;

for(i = 0; i<cc ; i++){
  size_t lenn = strlen(pb[i].name);
  if (pb[i].name[lenn - 1] == '\n') {
    pb[i].name[lenn - 1] = '\0';
  }
  fgets(pb[i].name, sizeof(pb[i].name), db);

  size_t lena = strlen(pb[i].address);
  if (pb[i].address[lena - 1] == '\n') {
    pb[i].address[lena - 1] = '\0';
  }
  fgets(pb[i].address, sizeof(pb[i].address), db);

  size_t lenc = strlen(pb[i].cellphone);
  if (pb[i].cellphone[lenc - 1] == '\n') {
    pb[i].cellphone[lenc - 1] = '\0';
  }
  fgets(pb[i].cellphone, sizeof(pb[i].cellphone), db);

  size_t lene = strlen(pb[i].email);
  if (pb[i].email[lene - 1] == '\n') {
    pb[i].email[lene - 1] = '\0';
  }
  fgets(pb[i].email, sizeof(pb[i].email), db);
}
Was it helpful?

Solution 2

As @unwind said, code is referencing uninitialized data before writing to it

  size_t lenn = strlen(pb[i].name);  // pb[i].name contents are not defined yet.
  ...
  fgets(pb[i].name, sizeof(pb[i].name), db);

Suggest creating a function to handle the reading of the line.

void ReadLine(FILE *db, char *dest, size_t size) {
  char buffer[size+2];
  dest[0] = '\0';
  if (fgets(buffer, sizeof buffer, db) != NULL) {
    size_t len = strlen(buffer);
    // Get rid of potential \n
    if (len > 0 && buffer[len-1] == '\n') buffer[--len] = '\0';
    strncpy(dest, buffer, size);
  }
} 


for(i = 0; i<cc ; i++) {
  ReadLine(db, pb[i].name, sizeof pb[i].name);
  ReadLine(db, pb[i].address, sizeof pb[i].address);
  ReadLine(db, pb[i].cellphone, sizeof pb[i].cellphone);
  ReadLine(db, pb[i].email, sizeof pb[i].email);
}

Additions could be made to ReadLine() to return EOF on NULL read, excessively long lines or \r concern as raised by @MadHatter. It's all in one function, so easier to maintain and enhance code.

OTHER TIPS

You can't reference data in the newly allocated array of Myphonebooktype before initializing it. You calls to strlen() all generate undefined behavior, since the struct members haven't been initialized.

Also, don't cast the return value of malloc() in C.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top