writing and reading within a fork - C

2019-09-20 10:22发布

问题:

The exercise is simple. The father process lets me write my name and surname in a file. The son process waits 5 seconds, then reads and displays it. I can't use the #wait() function.

#include <cstdlib>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char** argv) {
    char name[20];
    char surname[20];
    char outp[50];

    // The file pointer   
    FILE *file;
    // Open the file in write mode
    file = fopen("dati.txt", "w+");

    pid_t pid;
    pid=fork();
    if(pid>0){
        printf("Father");
        printf("Insert name: ");
        scanf("%s",name);

        for (int i=0; i<strlen(name); i++) {
            if (i==0) {
                if (name[i]>='a' && name[i]<='z')
                    name[i]-=32;
            } else {
                if (name[i]>='A' && name[i]<='Z')
                    name[i]+=32;
            }
        }

        printf("Insert surname: ");
        scanf("%s", surname); 

        for (int i=0; i<strlen(name); i++){
            if (i==0){
                if (surname[i]>='a' && surname[i]<='z')
                    surname[i]-=32;
            } else {
                if (surname[i]>='A' && surname[i]<='Z')
                    surname[i]+=32;
            }
        }
        fputs(name, file);
        fputs(" ",file);
        fputs(surname, file);
        printf("Father exits");
        fclose(file);
        exit(0);
    }else{
        sleep(5);
        // position to the start of the file
        rewind(file);    
        fgets(outp, 50, file);
        printf("Read string: %s", outp);        
        fclose(file);
        exit(0);
    }
    return 0;
}

If I insert name and surname before the 5th second, the program writes them, but doesn't display them. Otherwise, if I write the name and "accidentally" wait for the 5th second, it displays the file content (which are basically random characters).

回答1:

You are closing the file in the main process, then you want to reuse the same pointer in the child process. This is not possible. You need to reopen the file in the child process.

So, you need to write this after the sleep() call:

file = fopen("dati.txt", "r");

You also won't need the #rewind() function call, as you will be back at the start of the file.

UPDATE: The problem was that w+ means

write/update: Create an empty file and open it for update

So, you the file was erased. With r mode, it works just fine.

PS: By the way, you shouldn't use cstdio in a C program, use only the standard stdio.h header file. There was also a compilation error, because you are redeclaring the loop variable i.



回答2:

You need to fopen file after fork() both for parent and child separately:

if (pid > 0) {
    /* Parent process */
    file = fopen("dati.txt", "w+");
    /* write to file */
    ...
} else {
    /* child process */
    sleep(5);
    file = fopen("dati.txt", "r");
    /* read from file */
    ...
}

With this change it will work. Mind that, only the parent process is actively connected to your console - the output of child will show after 5 seconds and might appear after parent process exits (due to no call to wait). So you can see "Father exists" message and get console prompt before child will show any output.



标签: c fork fgets fputs