when copying strings from one text file to another, the last line in the original file is not copied

55 views Asked by At

edit: change the code to my real code, because i was told that the shortened one i posted couldn't be compiled. hope it helps in finding the problem

i have a struct as below:

struct patient {
    char name[30], ID[8];
    int age, phoneNo;
};

and i've written the code below:

int searchName()
{
    char search[30];
    char record[60];
    const char s[2] = ",";
    struct patient c;
    int foundRecord = 0, linectr = 0;
    char a[8], str[200], tempname[] = "tempfile.txt", filename[] = "patient.txt";
    int IDno, temp = 999999;

    FILE* fPtr, *fPtr2;
    fPtr = fopen(filename, "r");

    printf("Enter name to to replace phoneNo with 999999: ");
    getchar();
    fgets(search, 30, stdin);

    //remove the '\n' at the end of string
    search[strcspn(search, "\n")] = 0;

    printf("Record found: ");

    while (fgets(record, 60, fPtr))
    {
        // strstr returns start address of substring in case if present
        if (strstr(record, search))
        {
            char* pStr = strtok(record, ",");
            if (pStr != NULL) {
                strcpy(c.ID, pStr);
            }
            pStr = strtok(NULL, ",");
            if (pStr != NULL) {
                strcpy(c.name, pStr);
            }
            pStr = strtok(NULL, ",");
            if (pStr != NULL) {
                c.age = atoi(pStr);
            }
            pStr = strtok(NULL, ",");
            if (pStr != NULL) {
                c.phoneNo = atoi(pStr);
            }
            printf("\n%s\t%s\t%d\t%d", c.ID, c.name, c.age, c.phoneNo);
            foundRecord++;
        }

    }
    if (foundRecord = 0)
        printf("%s cannot be found\n", search);
    
    strcpy(a, c.ID);
    sscanf(a, "PT%d", &IDno);

    fPtr = fopen(filename, "r");

    fPtr2 = fopen(tempname, "w");

    while (!feof(fPtr))
    {
        strcpy(str, "\0");
        fgets(str, 100, fPtr);
        if (!feof(fPtr))
        {
            linectr++;
            if (linectr != IDno)
            {
                fprintf(fPtr2, "%s", str);
            }
            else
            {
                fprintf(fPtr2, "%s,%s,%d,%d\n", c.ID, c.name, c.age, temp);
            }
        }
    }
    fclose(fPtr);
    fclose(fPtr2);
    remove(filename);
    rename(tempname, filename);
    printf("\nReplacement successful. \n");
    return 0;
}

the code works like this: i have a bunch of strings in a text file called patient.txt, and i want to replace a string (IDno) in the text file with a string i have stored in struct patient c prior to this. the code works in creating another file and copying strings from the original file (patient.txt) into a new file while replacing the original string with the the new string, but i noticed that the last string in the original file always gets ignored. for example, i have 6 lines below stored in the original file:

PT1,John Doe,35,123456
PT2,Mary Ann,34,124684
PT3,John Lemmons,15,834945
PT4,James Bond,22,565453
PT5,Mary Sue,34,3435453
PT6,John Brown,54,3435346

when i search for Mary Ann to be replaced (line 2), only the first 5 lines (including the replaced 2nd line) get copied into the new file when i run my code. why is the last line not being copied? another issue is that the remove and rename functions in my code isn't working and i'm not sure why. would appreciate it if someone could explain how i can fix this.

2

There are 2 answers

1
anastaciu On BEST ANSWER

Using feof is most likely the problem, see Why is “while ( !feof (file) )” always wrong?, you can create a much simpler and effective while cycle using fgets return value as a stop condition:

while (fgets(str, 100, fPtr)) //when file ends stop
{
    linectr++;
    if (linectr != IDno)
    {
        fprintf(fPtr2, "%s", str);
    }
    else
    {
        fprintf(fPtr2, "%s,%s,%d,%d\n", c.ID, c.name, c.age, temp);
    }
}

There is also typo in if (foundRecord = 0), it should be ==, that is most certainly derailing your program.


1
Jabberwocky On

Replace all your while (!feof(fPtr)) loop with this:

    while (fgets(str, 100, fPtr) != NULL)
    {
        linectr++;
        if (linectr != IDno)
        {
            fprintf(fPtr2, "%s", str);
        }
        else
        {
            fprintf(fPtr2, "%s,%s,%d,%d\n", c.ID, c.name, c.age, temp);
        }
    }

There may be other problems though.

Off topic remarks:

  • you should check if fopen fails which actually happens very often in the real world.
  • drop the [15] in char tempname[15] = "tempfile.txt" -> char tempname[] = "tempfile.txt"