C: use of fgets() with file

356 views Asked by At

Good evening StackOverFlow. I typed a code which uses lists and files to manage an address book, now I have a problem with the function fgets(). In the procedure print_file() I used fgets() to read a line from the file and to store it into a string of, at the most, 200 characters. Debugging my code, I noticed that the file was popularized but after I extract the line with fgets() to store it into the string, the string results empty. Following I post the procedure print_file() and the procedure filling() which popularized the file with the nodes of the list. Anyone can help me?

void print_file(FILE* myfile, int num){
    char contact[200];
    int i=0;

    while(i<num){ 
        fgets(contact, 200, myfile);
        i++;
        printf("%d) %s", i, contact);
    }
    fclose(myfile);
}


void filling(FILE* myfile){
    list_struct* l; node_struct* new_node;
    node_struct* tempnode;
    t_contact temp;
    int n_contacts=0, i=0;

    printf("\n*****The file will be filled by a list*****\n");

    l=made_list(); //creating new list
    if(l!=NULL){
        printf("\nList successfully created\n");
    }
    printf("How many contacts do you want to add to the list?   ");
    scanf("%d", &n_contacts);

    for(i=1;i<=n_contacts;i++){
        printf("NAME > ");
        scanf("%s", temp.name);
        printf("SURNAME > ");
        scanf("%s", temp.surname);
        printf("TELEPHONE > ");
        scanf("%s", temp.telephone);
        printf("E-MAIL > ");
        scanf("%s", temp.email);
        printf("\n");
        new_node = made_node(temp); //creating new node
        add_node(l, new_node);
    }// end for --> the list has been popularized

    tempnode = l->head;
    while(tempnode!=NULL){
        fprintf(myfile, "%s %s %s %s\n", tempnode->content.name,   tempnode->content.surname, tempnode->content.telephone, tempnode->content.email);
        tempnode=tempnode->next;
    }
    print_file(myfile, n_contacts);
    fclose(myfile);

}

2

There are 2 answers

0
Les On

The way you've written it, fgets() will get called to read starting at the end-of-file. You can use fseek() to position to the start of file.

8
AndersK On

You need to reposition the file pointer at the start of the file in order to read from it. As you have it now it is at the end of the file when you call print_file.

rewind(fp) should do it.

EDIT:

based on your comment I would propose something like this instead note also that you are calling fclose() twice one time inside print_file and another time after you call print_file, this is definitely not good. Instead remove the fclose from the print_file function since the name implies that it only prints.

/* 
 * extracts a row from the file and then puts it into 
 * a string and prints the result
 * @param[in] myFile file pointer to file opened in rw access
 * @param[in] num number of rows in the file 
 */
void print_file(FILE* myfile, int num)
{
  char contact[200];  // allocate on stack
  int i = 0;

  if ( myfile != NULL )  // check argument to function
  {
    fflush(myfile);
    rewind(myfile);

    for (i = 0; i < num; ++i)
    {
      if (fgets(contact, sizeof(contact), myfile) != NULL);
      {
        printf("%d) %s", i + 1, contact);
      }
    }
  }
}

alternatively you could just read from start of file to end of file by reading each line and not caring about num:

  int i = 1;
  while (fgets(contact, sizeof(contact), myfile) != NULL);
  {
    printf("%d) %s", i++, contact);
  }