0

The details of the employees, i.e,employee id and no of files done by them needs to be stored in a file "employee.txt".Now, the total count of files stored into the file needs to be displayed. My program code,when compiled and executed, prints the output but at the end gives junk characters too. Here is my code:

    #include<stdio.h>
    #include<stdlib.h>
    struct emp
    {
        int emp_id;
        int nof;
    };
    int main()
    {
        int no,total=0;
        printf("Enter the number of employees\n");
        scanf("%d",&no);
        struct emp *e;
        e=(struct emp*)malloc(no*sizeof(struct emp));
        int i,j;
        FILE *fptr;


        fptr=fopen("employee.txt","wb");

        for(i=0;i<no;i++)
        {
        fflush(stdin);
        printf("For employee %d\n",i+1);
        printf("Enter the employee id\n");
        scanf("%d",&(e+i)->emp_id);
        printf("Enter the number of files done\n");
        scanf("%d",&(e+i)->nof);
        }
        fwrite(&e,sizeof(e),1,fptr);
        for(i=0;i<no;i++)
        {
            total=total+(e+i)->nof;
        }
        fprintf( fptr,"%d",total);
        fclose(fptr);

        printf("Total number of files done by all employees : ");

        FILE *fr;
        fr=fopen("employee.txt","rb");

        for(j=0;!feof(fr);j++)
        {
        fread(&e,sizeof(e),1,fr);
        fscanf(fr,"%d",&total);
        }
        fclose(fr);
        printf("%d",total);

      return 0;
    }

The expected output is: Input:

    Enter the number of employees
    3
    For employee 1
    Enter the employee id
    470
    Enter the number of files done
    5
    For employee 2
    Enter the employee id
    471
    Enter the number of files done
    3
    For employee 3
    Enter the employee id
    472
    Enter the number of files done
    1

Output:

    The number of files done by all employees : 9

But, my output is showing:

    The number of files done by all employees : 90/~

Please help me find the errors.I am new to C programming in files.
I also tried writing fprintf(stdout,"%d",total); after fprintf(fptr,"%d",total); thereby avoiding opening the file again in read mode and then scanning and printing "total" as the main objective is to simply display the total no of files stored. Still, the junk characters get displayed at the end.

  • 5
    `fflush(stdin)` has undefined behavior. `fflush` only makes sense on output handles. – melpomene Jul 09 '17 at 06:59
  • 4
    Possible duplicate of [Why is “while ( !feof (file) )” always wrong?](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – melpomene Jul 09 '17 at 07:00
  • 1
    1) `fwrite(&e,sizeof(e),1,fptr);` --> `fwrite(e,sizeof(*e),1,fptr);` 2) Delete `for(j=0;!feof(fr);j++)` 3) `fread(&e,sizeof(e),1,fr);` --> `fread(e,sizeof(*e),1,fr);` – BLUEPIXY Jul 09 '17 at 07:03
  • 1
    or Do `fwrite(e, sizeof(*e), no,fptr);` and `fread(e, sizeof(*e), no,fptr);` – BLUEPIXY Jul 09 '17 at 07:11
  • I removed the for loop (for checking the eof). That was not necessary in the code.Thank you for pointing out. I tried both the given suggestions for 'fwrite' and 'fread'. It didn't help. For some inputs, it is not showing any junk characters at the output, whereas for some, it is. It was working the same before changing the code. @BLUEPIXY – Manjari Mahato Jul 09 '17 at 07:26
  • I can't reproduce. – BLUEPIXY Jul 09 '17 at 07:31
  • 1
    try `printf("%d",total);` --> `printf("%d\n", total);` – BLUEPIXY Jul 09 '17 at 07:44
  • Tried that already. Gives the output and prints the junk character in new line. – Manjari Mahato Jul 09 '17 at 07:46
  • Is not it a shell prompt? – BLUEPIXY Jul 09 '17 at 08:02
  • Yes,it is. Now, i think the above code is fine, it may be a compiler prob? I tried the above code in few online compilers. Timeout occurs. However, in other few in which it runs without timeout,it gives the correct output as desired. – Manjari Mahato Jul 09 '17 at 08:32
  • I figured it out! The problem was with fwrite. I worked with fprintf and fscanf alone in the whole program and it turned out perfect. – Manjari Mahato Jul 09 '17 at 21:01
  • for ease of readability and understanding: 1) separate code blocks (for, if, else, while, do...while, switch, case, default) via a single blank line. 2) consistently indent the code. Indent after every opening brace '{'. unindent before every closing brace '}'. suggest each indent level be 4 spaces. 3) when defining structures, etc, surround them with a blank line before and after the definition 4) follow the axiom: *only one statement per line and (at most) one variable declaration per statement.* – user3629249 Jul 10 '17 at 00:07
  • when calling any of the `scanf()` family of functions, always check the returned value (not the parameter values) to assure the operation was successful. – user3629249 Jul 10 '17 at 00:09
  • when calling `fopen()`, always check (!=NULL) the returned value to assure the operation was successful. – user3629249 Jul 10 '17 at 00:10
  • when calling any of the heap allocation functions: (malloc, calloc, realloc) 1) always check (!=NULL) the returned value to assure the operation was successful. 2) the returned type is `void*` which can be assigned to any pointer. Casting just clutters the code, making it more difficult to understand, debug, etc. – user3629249 Jul 10 '17 at 00:12
  • variable names should indicate `content` or `usage` (or better, both), variable names like `e` are not really meaningful, even in the current context. – user3629249 Jul 10 '17 at 00:13
  • when calling `fread()`, always check the returned value against the 3rd parameter to assure the operation was successful. – user3629249 Jul 10 '17 at 00:14
  • regarding: `fwrite(&e,sizeof(e),1,fptr);` the expression: `sizeof(e)` will return the size of a pointer. Suggest: `fwrite(&e,sizeof(*e),1,fptr);` notice the addition of the dereference operator `*` – user3629249 Jul 10 '17 at 00:17
  • to avoid memory leaks, every pointer set by `malloc()` or `calloc()` or `realloc()` should be passed to `free() – user3629249 Jul 10 '17 at 00:19
  • when calling `fwrite()`, always compare the returned value with the third parameter to assure the operation was successful. – user3629249 Jul 10 '17 at 00:21
  • for ease of readability (the compiler does not care) insert a space after comma ',' and semicolon ';' and inside parens – user3629249 Jul 10 '17 at 00:22

0 Answers0