0

This program is for a homework assignment. Basically, text is read in from a file and a family tree is simulated. Here is sample input and output:

Input:

A B 3 C D X
D Y 2 M E
M F 0
C P 1 K

Output:

A-B
   C-P
      K
   D-Y
      M-F
      E
   X

Basically, the first two characters of each line are a "couple." Then the number represents the number of children that couple has, then the children are listed. The couple on the first line is the eldest, and couples later in the file may be children of other couples. (Clearly I have much more to do before my program accomplishes this exactly)

Regardless of what this program does, here is my issue: For each child that ends up having children, I want it to use the same for loop to create them. For example, the C-P couple needs to iterate through the loop ONCE to create K. Therefore, the values of i and numChilds are set to 0 and 1 respectively so that it iterates once. However, those values are reset once the loop starts iterating again. Look at the two parts of the program that I labeled for debugging. The variables should be the same in both places, but they revert to their previous values somehow. Maybe I don't fully understand how forking affects variable scope, but can someone please explain it to me? Is there a way I can fix this or do I need to implement a new solution?

#include <stdio.h>
#include <sys/types.h>


int main (int argc, char* argv[] ){

   pid_t pid;

   FILE* inFile = fopen(argv[1], "r");

   if(inFile==0){
      printf( "Error opening file, terminating program\n");
      return 1;
      }

   char person;
   char partner;
   int numChilds;

   int inInt;
   int i=0;

   // boolean flag
   int match;

   // prime the loop by importing the first two parents
   inInt = fgetc(inFile);
   while(inInt<33){
      inInt = fgetc(inFile);
      }
   person = (char) inInt;

   inInt = fgetc(inFile);
   while(inInt<33){
      inInt = fgetc(inFile);
      }
   partner = (char) inInt;

   printf("\n%c-%c\n", person, partner);

   // get number of children for first pair
   inInt = fgetc(inFile);
   while(inInt<33){
      inInt = fgetc(inFile);
      }
   numChilds = inInt - 48;

   // loop once for each new child to be created
   for(i=0; i<numChilds; i++){

//////////DEBUGGING///////////////////////////////
      /*
      printf("%i", i);
      printf("%i", numChilds);
      printf("%c", '\n');
      */
//////////DEBUGGING///////////////////////////////


      // get name of next child from file, set it as current person
      inInt = fgetc(inFile);
      while(inInt<33){
         inInt = fgetc(inFile);
         }
      person = (char) inInt;

      pid = fork();

      if(pid == 0){ // child process

         // search for self in file to find partner
         match = 0;
         while(((inInt = fgetc(inFile)) != EOF) && match==0){ 

            // if match found
            if((char) inInt == person){

               // set flag to stop searching file
               match = 1;

               // grab partner which is next name in file
               inInt = fgetc(inFile);
               while(inInt<33){
                  inInt = fgetc(inFile);
                  }
               partner = (char) inInt;

               // grab number of children for that pair
               inInt = fgetc(inFile);
               while(inInt<33){
                  inInt = fgetc(inFile);
                  }
               numChilds = inInt - 48;
               printf("%i", numChilds);

               // reset for loop index so it will now execute for child processes
               i=0;

               }
            }

         // if partner was never found, child will have no children, so force for loop to stop
         if(match==0){
            i = numChilds;
            }

         printf("\n%c-%c\n", person, partner);

//////////DEBUGGING///////////////////////////////
/*
         printf("%i", i);
         printf("%i", numChilds);
         printf("%c", '\n');
*/
//////////DEBUGGING///////////////////////////////

         }

      else if(pid>0){ // parent process
         wait(NULL);
         }

      }

   return 0;
   }
Bobazonski
  • 1,515
  • 5
  • 26
  • 43
  • not your problem but have you considered using printf like: `printf("\n%c-%c\n", person, partner);`? – Luis Sep 17 '14 at 15:29
  • I'm new to C, I've been using C++ forever which has `cin` and `cout`. I didn't understand until now but your example makes sense. Thank you – Bobazonski Sep 17 '14 at 15:31
  • I'm confused, why do you think they should be the same in both places? Your code is explicitly changing the values of both of those variables between the debug statements. I.e. `numChilds = inInt - 48;` and `i=0;` in the child process code. – Luis Sep 17 '14 at 15:51
  • much similar to the C++ printf :) http://www.cplusplus.com/reference/cstdio/printf/ – Luis Sep 17 '14 at 15:52
  • Does the assignment require you to use `fork`? – pat Sep 17 '14 at 16:11
  • The purpose of the assignment is the usage of `fork`. I understand now that while the variables are changed within the child function, the for loop is still looking at the variables provided from the parent. Is there an alternate method of accomplishing my goal? – Bobazonski Sep 17 '14 at 17:44

1 Answers1

0

A call to fork will copy the stack (where variable are stored) and the program (the code) in memory then run a new process starting right after the fork call in the forked program.

Two forked process will have different stack and will run with different variables.

You may read http://linux.die.net/man/2/fork for a complete description of fork behaviour.

To communicate between process you may use shared memory : How to share memory between process fork()?

Community
  • 1
  • 1
SkyDream
  • 382
  • 1
  • 10