You are here:

C/Unexpected Output

Advertisement


Question
The Unexpected Output
The Unexpected Output  
QUESTION: Hello Expert,
I have a problem in C File I/O program. The part where the problem lies is given below:

void list_member(void)
{
   FILE *listPtr;
   clrscr();
   if((listPtr=fopen("members_list.final","rb+"))==NULL)
   {
       printf("\nCANNOT OPEN FILE. RETURNING TO MAIN MENU.");
       gotoxy(1,25);
       getch();
       main();
   }
   fflush(stdin);
   rewind(listPtr);
   while(fread(&list,list_size,1,listPtr)==1)
       printf("\n%15s %-15s %-15s", list.fname, list.sname, list.mobile);
   fclose(listPtr);
   getch();
   main();
}

As you can see, this function reads a file and displays the contents. If I normally open the program and operate this function, it works flawlessly. But if I add record through a different function and then access this function without terminating the program, the last inputted data gets appended at the end of mobile number. What is causing this? I want only Name and Mobile Number displayed.
I have attached an image of what the problem looks like.

Regards,
Parixyt.

ANSWER: Hello
It is difficult to say what the problem might be without seeing the other function. Check to make sure that you are writing the correct number of bytes when writing records to the file. You may be writing short records, and then reading a long record in the list_member. That would cause you to read more data than you need. Check the return values of fread and fwrite to see how many bytes are being transferred.

When writing records to the file, make sure that all strings (fname, lname, mobile) end with a 0 byte. The 0 byte should be read back in so that printf does not print more data than it should.

Good luck.

---------- FOLLOW-UP ----------

QUESTION: Thank you for the response. But still I can't figure it out. I used different files for the add_member and list_member functions. Following are the missing code snippets:

/*Structures*/
struct member_data {
  int id;
  char fname[100], sname[100];
  char mobile[10];
  char address[100];
  int year, month, date;
  int rank;
};
struct member_data mem;
long int mem_size = sizeof(mem);

struct list_data {
  char fname[100], sname[100];
  char mobile[10];
};
struct list_data list;
long int list_size = sizeof(list);

int reg_id; /*Variable to hold Registration ID (automatic incremental integer */

void add_member(void)
{
  FILE *memPtr;
  FILE *listPtr;
  FILE *reg_id_Ptr;

  char another = 'Y';

  if((memPtr = fopen("members.final","ab+"))==NULL)
  {
     puts("CANNOT OPEN FILE. RETURINING TO MAIN MENU.");
         getch();
     main();
  }

  fflush(stdin);
  fseek(memPtr,0,SEEK_END);

  while(another=='Y')
  {
     clrscr();
     reg_id_Ptr = fopen("reg_id.final","r");
     do {
        reg_id = fgetc(reg_id_Ptr);
     } while(!EOF);
     fclose(reg_id_Ptr);

     reg_id = reg_id++;

     printf("\nRegistration Number      : %d", reg_id);
     printf("\nName          : ");
     scanf("%s %s", mem.fname, mem.sname);
     printf("\nPost          : ");
     scanf("%d", mem.rank);
     printf("\nDate Joined (Numerical)");
     printf("\n\tYear         : ");
     scanf("%d", &mem.year);
     printf("\n\tMonth         : ");
     scanf("%d", &mem.month);
     printf("\n\tDate         : ");
     scanf("%d", &mem.date);
     printf("\nContact Number      : ");
     scanf("%s", mem.mobile);
     printf("\nAddress          : ");
     scanf("%s", mem.address);
     mem.id = reg_id;
     fflush(stdin);

     strcpy(list.fname, mem.fname);
     strcpy(list.sname, mem.sname);
     strcpy(list.mobile, mem.mobile);

     fwrite(&mem,mem_size,1,memPtr);
     fflush(stdin);
     gotoxy(1,25);
     printf("Record sucessfully added. Add another? (Y/N) ");
     reg_id_Ptr = fopen("reg_id.final","wb");
     fputc(reg_id,reg_id_Ptr);
     fclose(reg_id_Ptr);
     fclose(memPtr);
     if((listPtr = fopen("members_list.final","ab+"))==NULL)
     {
        puts("CANNOT OPEN FILE. RETURINING TO MAIN MENU.");
        main();
     }

     fflush(stdin);
     fseek(listPtr,0,SEEK_END);
     fwrite(&list,list_size,1,listPtr);
     fclose(listPtr);

     another = toupper(getche());
  }
  fflush(stdin);
  main();
}

I am pretty sure this is where the problem lies. Please help me out. Thanks again.

Regards,
Parixyt.

Answer
Hello Parixyt

I think the problem is that the mobile field in the member_data and list_data is too short. The char array needs space for the null terminator byte. From your picture it looks like the mobile data is 10 characters long so the mobile field should be at least 11. Be generous, make it 20 in both structures. Once you change the field size, the existing data files will no longer work with the new version of the program, so be sure to erase the data files.

There are a few other problems I see. Your program functions should never call main. Instead they should return to main. The line reg_id = reg_id++ does not do what you expect. x++ increments x and then returns the old value of x, so x=x++ has no effect. The old value of x goes back into x. All you need is reg_id++; The reg_id is an integer, so you should be writing 4 bytes with fwrite, instead of using fputc. The fputc takes a character as an integer but it writes a character (1 byte) to the file.

If you still cannot fix it, send the whole program as attachments to zlatko.c.help at gmail along with a short explanation about how to reproduce the problem and I'll help you out more.

C

All Answers


Answers by Expert:


Ask Experts

Volunteer


Zlatko

Expertise

No longer taking questions.

Experience

No longer taking questions.

Education/Credentials
No longer taking questions.

©2012 About.com, a part of The New York Times Company. All rights reserved.