Home > Blockchain >  How to update struct text file line by line
How to update struct text file line by line

Time:01-03

My code store all activities details in a file and I have problem accessing data in that file by searching using id. This is my add activities function and struct.

struct activities{
    char id[5];
    char actName[200];
    char date[20];
    char day[20];
}act;
//function to add volunteering activities
void addAct(){
    FILE *fileAct;
    
    //prompt user to enter activities details
    printf("\n\t Planning Volunteering Activities");
    printf("\n\t -----------------------------------");
    printf("\n\t Program ID \t: ");
    scanf(" %[^\n]%*c", &act.id);
    printf("\t Name of Activity : ");
    scanf(" %[^\n]%*c", &act.actName);
    printf("\t Date \t\t: ");
    scanf(" %[^\n]%*c", &act.date);
    printf("\t Day \t\t: ");
    scanf(" %[^\n]%*c", &act.day);
    
    //create & write in file activity
    fileAct = fopen("Activity", "a");
    
    fprintf(fileAct, "\n\t %s \n", act.id);
    fprintf(fileAct, "1. Name of Activity : %s \n", act.actName);
    fprintf(fileAct, "2. Date : %s \n", act.date);
    fprintf(fileAct, "3. Day : %s \n", act.day);
    
    //close file activity
    fclose(fileAct);
}

And this is my update function.

void updateAct(){
    //variable declaration
    char progID[5];
    
    //open activity file
    FILE *fp = fopen ("Activity", "r");
    
    //prompt user to search activities to update
    printf("\t Search by Program ID : ");
    scanf(" %[^\n]%*c", &progID);
   
    while( !feof(fp)){
        fread (&act, sizeof(struct activities), 1, fp);
        
        if (strcmp(progID, act.id) == 0)
            printf("%s %s", act.id, act.actName);
    }
    fclose(fp);
}
    

In the update function above, I couldnt access the act.id in struct based on user search, instead, the program display the whole data in the file. How can fix this problem?

CodePudding user response:

You provide pointers to char arrays, which technically is a pointer to a pointer. But scanf only needs pointers.

Remove the &'s of the scanf()-calls and add a maximum lengt specifier to your format arguments:

Change

scanf(" %[^\n]%*c", &progID);

to

scanf(" %4[^\n]%*c", progID);

for a 5 byte buffer.

CodePudding user response:

void readLine(char* message, char* buffer, int buffer_size)
{
    printf("\t%s: ", message);
    fgets(buffer, buffer_size, stdin);
    // fgets inserts '\n' at the end
    // we are removing it
    buffer[strlen(buffer) - 1] = '\0'; 
}

void addAct(){
    FILE *fileAct;
    struct activities newAct;
    //prompt user to enter activities details
    printf("\n\tPlanning Volunteering Activities");
    printf("\n\t-----------------------------------\n");

    readLine("Program ID", newAct.id, sizeof(newAct.id));
    readLine("Name of Activity", newAct.actName, sizeof(newAct.actName));
    readLine("Date", newAct.date, sizeof(newAct.date));
    readLine("Day", newAct.day, sizeof(newAct.day));

    //create & write in file activity
    fileAct = fopen("Activity", "ab ");
    if(NULL != fileAct) {
        fwrite(&newAct, sizeof(struct activities), 1, fileAct);
        //close file activity
        fclose(fileAct);
    }
}

void updateAct(){
    //variable declaration
    char progID[5];
    struct activities readAct;
    //open activity file
    FILE *fp = fopen("Activity", "rb");
    if(NULL != fp) {
        //prompt user to search activities to update
        printf("\tSearch by Program ID : ");
        fgets(progID, sizeof(progID), stdin);
        progID[strlen(progID) - 1] = '\0';
        while(fread(&readAct, sizeof(struct activities), 1, fp) != 0){
            if (strcmp(progID, readAct.id) == 0)
            {
                printf("%s %s\n", readAct.id, readAct.actName);
                break;
            }
        }
        fclose(fp);
    }
}
  • Related