2

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);
}
unwind
  • 391,730
  • 64
  • 469
  • 606
user3266210
  • 299
  • 4
  • 15
  • Try checking for `\r` also, i.e. replace with `\0` if you find `\n` or `\r` – 0xF1 Feb 07 '14 at 13:18
  • 2 bruce wayne mansion 88888888 batman@hero.com john yeung 46 linggo 9393293226 my@yahoo.com my db.txt looks like this – user3266210 Feb 07 '14 at 13:20
  • @user3266210 Put that in the question, it's impossible to understand the exact structure in a comment. – unwind Feb 07 '14 at 13:24
  • if you are doing `lenn = strlen(pb[i].name)` then I suppose `pb[i].name[lenn - 1]` will always be `\0`... – 0xF1 Feb 07 '14 at 13:24

2 Answers2

3

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.

Community
  • 1
  • 1
unwind
  • 391,730
  • 64
  • 469
  • 606
0

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.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256