1

I have this program where I can input the number of students, their names, and their corresponding grades for prelims, midterms, and finals. All of these user inputted data will be put on a text file.

I tried to create an edit function to update a specific line that contains a student's name and grades on the text file.

But instead of replacing it with newly updated data, it deletes it.

Here's my source code for the write function and getScore function, which will allow the user to input data (such as student name and grades) to the text file:

#define max 256

    void write()
    {
        system("cls");
        printf("\n Enter the number of students: ");
        scanf("%d", &numberOfStudents);
    
        FILE *fp;

    fp = (fopen("studentRecord.txt", "a"));
    if (fp == NULL)
    {
        printf("\n Error!");
        exit(1);
    }

    fprintf(fp, " Name \t \t Prelims \t Midterms \t Finals \t Average \t Rating \n");
    for (i = 0; i < numberOfStudents; ++i)
    {
        printf("\n Student No. %d ", i + 1);
        getScore(studentName, &prelims, &midterms, &finals);

        /******This is just another function for computing the average scores******/
        averageScores = average(prelims, midterms, finals);

        /******This is just also another function for rating the average scores******/
        rating = rate(averageScores);

        fprintf(fp, " %d.) %s \t %d \t \t %d \t \t %d \t \t %.2f \t \t %.2f \n", i + 1, studentName, prelims, midterms, finals, averageScores, rating);
    }

    fclose(fp);
    printf("\n \n File studentRecord.txt is saved!");
    getch();
    view();
}

void getScore(char *studentName, int *prelims, int *midterms, int *finals)
{
    printf("Name: ");
    scanf("%s", studentName);

    printf("\n \t Prelims: ");
    scanf("%d", prelims);

    printf("\n \t Midterms: ");
    scanf("%d", midterms);

    printf("\n \t Finals: ");
    scanf("%d", finals);
}

Here's my source code for the edit function, which should allow the user to edit a specific line on the text file:

void edit()
{
    system("cls");
    FILE *fpo;
    FILE *fp2;

    int lno, linectr = 0;
    char str[max];
    char newln[max], temp[] = "temp.txt";

    printf("\n Input the file to be opened: ");
    fgets(file_name, max, stdin);
    file_name[strlen(file_name) - 1] = '\0';

    fpo = fopen(file_name, "r");

    if (!fpo)
    {
        printf("\n Unable to open the input file!");
        main();
    }

    fp2 = fopen(temp, "w");
    if (!fp2)
    {
        printf("\n Unable to open a temporary file to write!");
        fclose(fpo);
        main();
    }

    printf("\n Input the line number you want to update: ");
    scanf("%d", &lno);


    printf("\n Student No. %d ", lno);
    getScore(studentName, &prelims, &midterms, &finals);
    averageScores = average(prelims, midterms, finals);
    rating = rate(averageScores);

    fprintf(fp, " %d.) %s \t %d \t \t %d \t \t %d \t \t %.2f \t \t %.2f \n", lno, studentName, prelims, midterms, finals, averageScores, rating);

    lno++;


    while (!feof(fpo))
    {
        strcpy(str, "\0");
        fgets(str, max, fpo);
        if (!feof(fpo))
        {
            linectr++;
            if (linectr != lno)
            {
                fprintf(fp2, "%s", str);
            }
            else
            {
                fprintf(fp2, "%s", newln);
            }
        }
    }

    fclose(fpo);
    fclose(fp2);
    remove(file_name);
    rename(temp, file_name);
    getch();
    view();
}

When compiled and run, it goes like this:

These are the user inputted data in the text file These are the user inputted data in the text file

And this is when I try to update line number 3's data this is when I try to update line number 3's data

Lastly, this is when I try to view to updated contents of the text file that should've included the new data. this is when I try to view to contents of the text file

The line that should've been updated is rather deleted.

Please check my code if there's anything wrong with it. It would be a great help someone pointed out the error

Liyanna
  • 119
  • 10
  • 2
    [Why `while(!feof(file))` is always wrong](https://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) – Barmar Feb 05 '22 at 09:41
  • You never fill in `newln`. It's an unitialized string, and you're replacing the selected line with that. – Barmar Feb 05 '22 at 09:43
  • There's no need to do `strcpy(str, "\0");` before `fgets(str, max, fpo);` – Barmar Feb 05 '22 at 09:43
  • Unrelated, but it just killed me when I saw this: `strcpy(str, "\0");` - Um... First off, the embedded nulchar is redundant. There's already one at the tail of the string literal so, `strcpy(str, "");` would work. Second, don't do that either. All you're really trying to do is set a nulchar as the first entry in that buffer, so... do that: `*str = 0;` . Done. – WhozCraig Feb 05 '22 at 09:44
  • @WhozCraig: furthermore why initialize `str` in the first place? `fgets()` will store the line into it if successful and the loop should be exited otherwise. – chqrlie Feb 05 '22 at 10:11
  • Please learn how to use a debugger - SO is not a serial debugging service. https://stackoverflow.com/q/70975656/758133 – Martin James Feb 05 '22 at 12:05

1 Answers1

1

The copying loop uses feof() to try and detect end of file, but this method is incorrect: you should just use the return value of fgets(), which will be a null pointer if no line could be read from the file.

    while (fgets(str, max, fpo)) {
        linectr++;
        if (linectr == lno) {
            fputs(newln, fp2);
        } else {
            fputs(str, fp2);
        }
    }

For further explanations, read Why is “while ( !feof (file) )” always wrong?

Note also that you should use snprintf instead of fprintf to compose the new line contents:

sprintf(newln, sizeof newln, " %d.) %s \t %d \t \t %d \t \t %d \t \t %.2f \t \t %.2f \n",
        lno, studentName, prelims, midterms, finals, averageScores, rating);

The line number should not be updated either: remove the lno++; statement.

chqrlie
  • 131,814
  • 10
  • 121
  • 189