0

I'm using Dev-C++ (we're required to use either Turbo-C++ or Dev-C++). I'm supposed to delete one student (DATA 2) from a student record. Here is the data that we were given:

DATA 1:

2021-10-693 Clarisse BSCS 1 1.00, 1.00, 1.00, 1.25, 1.25

DATA 2:

2021-10-705 Kricel BSCS 1 1.00, 1.25, 1.00, 1.00, 1.25

DATA 3:

2021-01-256 Rafael BSCS 1 1.00, 1.00, 1.00, 1.00, 1.25

We were given a student.dat file created using Turbo-C++ but I can't open it in Dev-C++ so I created my own student.dat by copy-pasting my teacher's code from Turbo-C++ to Dev-C++. The only thing I changed in this code is removing clrscr(); and replacing it with system("cls");:

/* This program will allow saving of records in the disk */

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
typedef struct{
             char  No[12];
             char  Name[25];
             char  Crsyr[10];
             float Grade[5];
          }Student_Record;
int main()
{
  FILE  *STUDFILE;         /* defining FILE variable */
  Student_Record   STUDENT[50],TEMPREC;
  int i,j,ns;
  float TGrade;
  char Temp,FName[15];

  do{
        system("cls");
        printf("How many student records (max. of 50) ? ");
        scanf("%d",&ns);
        if ((ns<1)||(ns>50))
            {
             printf("\nInvalid Input!!!");
             printf("\n\nPress Any Key To Continue...");
             getch();
            }
  }while((ns<1)||(ns>50));
  scanf("%c",&Temp);
  for(i=0;i<ns;i++)
     {
         system("cls");
         printf("<@@ STUDENT's INFORMATION @@>\n\n");
         printf("Student No.    : ");
         gets(STUDENT[i].No);
         printf("Student Name   : ");
         gets(STUDENT[i].Name);
         printf("Course and Year: ");
         gets(STUDENT[i].Crsyr);
         printf("List of grades:\n");
         for(j=0;j<5;j++)
            {
              printf("\tGrade No. %d => ",j+1);
              scanf("%f",&TGrade);
              STUDENT[i].Grade[j]=TGrade;
            }
         printf("\nPress any key to continue...");
         getch();
         scanf("%c",&Temp);
     }
     printf("\n\nEnter Filename where records will be saved => ");
     gets(FName);
     printf("\n\nSaving of Records being process...");

     STUDFILE=fopen(FName,"w");    /* fopen-file opening; "w" - generate new file or overwrite existing file */

     for(i=0;i<ns;i++)
         {
          TEMPREC=STUDENT[i];
          fwrite(&TEMPREC,sizeof(TEMPREC),1,STUDFILE); /* fwrite - save records in the disk */
         }
     fclose(STUDFILE); /* fclose - file closing */

     printf("Saving of Records Completed!!!\n\n");
     printf("Press Any Key To Exit...");
     getch();
     return (0);
}

Here is the student.dat file:

2021-10-693 Clarisse    þÿÿÿÿÿÿÿþÿÿÿÿBSCS 1       €?  €?  €?  ?  ?2021-10-705 Kricel  Po     `Of°û   BSCS 1       €?   ?  €?  €?   ?2021-10-256 Rafael °û  ˜im°û  ˜im°ûBSCS 1       €?  €?  €?  €?   ?

My plan is to:

  1. Open student.dat for reading
  2. Open temp.dat for writing
  3. Read content of student.dat
  4. Compare studNo to data in student.dat
  5. If studNo is not equal to student no. of Kricel, write it in temp.dat
  6. If studNo is equal to student no. of Kricel, don't write in temp.dat
  7. Close both files
  8. Open temp.dat for reading
  9. Open student.dat for writing
  10. Overwrite student.dat with content from temp.dat
  11. Close both files
  12. Open student.dat for reading
  13. Display student.dat

And here is my code:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

typedef struct
{
    char no[12];
    char name[25];
    char crsYr[10];
    float grade[5];
} studentRecord;

int main()
{
    FILE *studFile, *tempFile;
    studentRecord student[50], tempStudRec, tempFileRec;
    int i = 0, j = 0, k = 0, found = 0;
    float tGrade = 0.00;
    char temp, fName[15], studNo[12], resp1, resp2;
    
    system("cls");
    
    printf("Enter file name of the record you want to alter: ");
    gets(fName);
    printf("Enter student no. of student you want to delete: ");
    gets(studNo);
    printf("Are you sure you want to remove this student (Y/N)? ");
    scanf("%c", &resp1);
    
    if (toupper(resp1) == 'Y')
    {
        printf("\nRetrieving records from %s...", fName);
        //Sleep(2000);
        printf("\nDeleting student %s from %s...", studNo, fName);
        //Sleep(2000);
    
        // Opens both files
    
        studFile = fopen(fName, "r");
        if (studFile == NULL)
        {
            printf("File opening is unsuccessful.");
            return 1;
        }
        
        tempFile = fopen("temp.dat", "w");
        
        // Reads student.dat
        
        k = 0;
        fread(&tempStudRec, sizeof(studentRecord), 1, studFile);
        while(!feof(studFile))
        {
            student[k] = tempStudRec;
            fread(&tempStudRec, sizeof(studentRecord), 1, studFile);
            k++;
        }
        
        // Compare studNo to data in student.dat
        
        for (i = 0; i < k; i++)
        {
            // If content is not equal to student no. of Kricel
            if (strcmp(studNo, student->no) != 0)
            {
                // Write in temp.dat
                tempFileRec = student[i];
                fwrite(&tempFileRec, sizeof(studentRecord), 1, tempFile);
            }
        }
        
        // Closes both files
        
        fclose(studFile);
        fclose(tempFile);
        
        // Opens both files again
        
        tempFile = fopen("temp.dat", "r");
        if (tempFile == NULL)
        {
            printf("File opening is unsuccessful.");
            return 1;
        }
        
        studFile = fopen(fName, "w");
        
        // Reads temp.dat
        
        k = 0;
        fread(&tempFileRec, sizeof(studentRecord), 1, tempFile);
        while(!feof(studFile))
        {
            student[k] = tempFileRec;
            fread(&tempFileRec, sizeof(studentRecord), 1, tempFile);
            k++;
        }
        
        // Copies temp.dat content to student.dat
        
        for (i = 0; i < k; i++)
        {
            // Write in student.dat
            tempStudRec = student[i];
            fwrite(&tempStudRec, sizeof(studentRecord), 1, studFile);
            
        }
        
        // Closes both files
        
        fclose(studFile);
        fclose(tempFile);
        
        // Opens student.dat for reading
        
        studFile = fopen(fName, "r");

        // Displaying records
    
        printf("Student deleted!");
        printf("\nDo you want to view record (Y/N)? ");
        scanf("%c", &resp2);
        
        if (toupper(resp2) == 'Y')
        {
            for(i = 0; i < k; i++)
            {
                system("cls");
                
                printf("<@@ STUDENT INFORMATION @@>\n\n");
                printf("Student No.    : %s\n", student[i].no);
                printf("Student Name   : %s\n", student[i].name);
                printf("Course and Year: %s\n", student[i].crsYr);
                printf("List of Grades:\n");
                for(j = 0; j < 5; j++)
                {
                    printf("\tGrade No. %d => %0.2f\n", j + 1, student[i].grade[j]);
                }
                printf("\nPress any key to continue...");
            }
        }
        
        // Closes student.dat
        
        fclose(studFile);
    }
    
    return 0;
}

This is what the output looks like:

Enter file name of the record you want to alter: student.dat
Enter student no. of student you want to delete: 2021-10-705
Are you sure you want to remove this student (Y/N)? Y

Retrieving records from student.dat...
Deleting student 2021-10-705 from student.dat...
--------------------------------
Process exited after 16.78 seconds with return value 3221225477
Press any key to continue . . .

I checked student.dat after running the code and it's empty. Meanwhile, temp.dat contains all the contents of student.dat I showed above, including the student I'm supposed to delete. Can anyone give me an idea why is student.dat empty after running this program? And why wasn't student 2021-10-705 deleted? I'm having a hard time understanding online tutorials since we kinda just skimmed over pointers and we haven't discussed malloc(), etc. yet.

banana
  • 13
  • 6
  • Why did you delete your other question with exactly the same content? – the busybee Mar 29 '22 at 08:05
  • 1
    You might want to read [why you should never ever use gets](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) and also [Why is “while ( !feof (file) )” always wrong?](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – Gerhardh Mar 29 '22 at 09:00
  • This does not really make much sense: `if (resp1 == toupper('y'))` If you want `Y` you can just write `Y`. If you want to allow both cases, you need to modify `resp1`, not `'y'` accordingly. – Gerhardh Mar 29 '22 at 09:02
  • @Gerhardh Oh yeah I did it the other way around lol. Thanks for pointing it out. – banana Mar 29 '22 at 09:37
  • @thebusybee I posted the wrong code for the program that produced the student.dat file. – banana Mar 29 '22 at 09:39
  • OK, but you know that you can [edit] your question, don't you? – the busybee Mar 29 '22 at 10:02

1 Answers1

2

Rather than analyzing your two programs for you, I'll try to suggest how you can figure out what's going on.

Check library function call return values

Library function calls don't always succeed! When you try to open a new file - the directory might not be writeable; when you write data to disk - the disk may be full; etc. I'm not saying this is what happens in your case, but you should rarely, or perhaps never, assume a library function succeeds, if its return value can indicate an error.

Always check that return value; and if it doesn't indicate success, print a message describing the failure. See, for example, answers to this question:

Error handling in C code

on how that looks.

Use a debugger

It is often not sufficient to just scrutinize the code, or deduce from the output what actually happens when the program runs. You can, and probably should, actively debug a misbehaving program by tracking its execution with a debugger program.

Here are two Stackoverflow questions about debugging on Linux and on Windows:

(other platforms also have debugging tools available.)

Consider flushing the standard output stream

When your program does not seem to run to conclusion, you could insert fflush() calls at relevant 'suspicious' points in your code to ensure that whatever you printed up to that point does actually become visible on the output, rather than waiting in the output stream's buffers.

Note that, other than for debugging purposes, we generally want to avoid flushing.

einpoklum
  • 118,144
  • 57
  • 340
  • 684