0

I am trying to read in a text file simulating CPU scheduling, perform the scheduling algorithm, and printing out the output.

i.e. process id number, arrival time, burst time

1 0 3
2 4 6
...

How can I assign the size of the struct to be created with the amount of lines scanned? Can I define MAX as the number of lines scanned? I am able to scan the input file and output the file, however, I have my MAX variable for the struct defined as 10000. The problem with this is that it prints to the file the correct output, but prints 0 0 0 up to 10000 lines after the input lines stop. Here's my functions.

#include<stdio.h>
#include<stdlib.h>
#define MAX 10000



typedef struct 
{
    int pid;
    int arrTime;
    int burTime;
    int finTime;
    int waitTime;
    int turnTime;

}Process;

Process pTable[MAX];


void readTable(char *fileName, Process pTable[MAX])
{

    int i;
    FILE *fileIN = fopen(fileName, "r+");



    while(!feof(fileIN))
    {
        fscanf(fileIN, "%d %d %d", &pTable[i].pid, &pTable[i].arrTime, &pTable[i].burTime);
        i++;
    }



    fclose(fileIN);

}


void printTable(char *fileName, Process pTable[MAX])
{

    FILE *fileOUT = fopen(fileName,"w+");



    for(int i=0; i < MAX;i++)
    {
    fprintf(fileOUT, "%d %d %d\n",pTable[i].pid, pTable[i].arrTime, pTable[i].burTime);
    } 


}

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

    readTable(argv[1], pTable);
    printTable(argv[2], pTable);


}

Here's the output I'm given for the shortened input file.

1 0 3
2 4 6
3 9 3
4 12 8
5 13 11
6 18 19
7 19 2
8 23 4
9 28 1
10 31 3
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0

1 Answers1

1

I would count lines of the file:

int lines = 0;
while(!feof(fp))
{
  ch = fgetc(fp);
  if(ch == '\n')
  {
    lines++;
  }
}

Then use malloc to dynamically create the struct on the heap.

HOW TO DO? This solution is to answer your specific question which regards a dynamically allocated array.

#include<stdio.h>
#include<stdlib.h>

typedef struct PROCESS
{
    int pid;
    int arrTime;
    int burTime;
    int finTime;
    int waitTime;
    int turnTime;

} process_t;

process_t** pTable;

int numLines = 0;

int getNumLines(char* fileName) {
    int lines = 0;
    int ch;
    FILE *fp = fopen(fileName, "r+");
    while(!feof(fp))
    {
        ch = fgetc(fp);
        if(ch == '\n')
        {
            lines++;
        }
    }
    return lines;
}

void readTable(char *fileName)
{
    /** Create process table **/
    pTable = malloc(sizeof *pTable);
    numLines = getNumLines(fileName);
    //TODO check numLines > 0
    numLines++; //because we counted from 0!

    int i;
    for(i = 0; i < numLines; i++) {
        pTable[i] = malloc(sizeof(*pTable));
        if(!pTable[i]) {
            printf("Can not allocate memory for pTable!\r\n");
            exit(-1);
        }
    }

    /** Do your stuff **/
    FILE *fileIN = fopen(fileName, "r+");
    i = 0; //
    while(i < numLines) //feof is problematic!
    {
        fscanf(fileIN, "%d %d %d", &pTable[i]->pid, &pTable[i]->arrTime,
               &pTable[i]->burTime);
        i++;
    }

    fclose(fileIN);
}  

void printTable(char *fileName)
{
    FILE *fileOUT = fopen(fileName,"w+");

    //numLines must have been filled in a previous function
    int i;
    for(i=0; i < numLines;i++)
    {
        fprintf(fileOUT, "%d %d %d\n", pTable[i]->pid, pTable[i]->arrTime,
                pTable[i]->burTime);
    } 
}

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

    readTable(argv[1]);
    printTable(argv[2]);

    return 0;
}

What is best? As Mr. Fabre explained, you are fine if you now your MAX value is always greater than expected lines in the input file. In that case, you simply pass the number of lines read in the readTable function into printTable function and replace it with the MAX which you are doing the loop condition.

Here is the solution using a big enough MAX:

#include<stdio.h>
#include<stdlib.h>

#define MAX 10000 //large enough number

typedef struct
{
    int pid;
    int arrTime;
    int burTime;
    int finTime;
    int waitTime;
    int turnTime;

}Process;

Process pTable[MAX];

//returns number of lines read
int readTable(char *fileName, Process pTable[MAX])
{
    int i = 0; //always init your variables or else you get garbage results
    FILE *fileIN = fopen(fileName, "r+");
    while(!feof(fileIN))
    {
        fscanf(fileIN, "%d %d %d", &pTable[i].pid, &pTable[i].arrTime, &pTable[i].burTime);
        i++;
    }

    fclose(fileIN);

    return i; //number of processed lines
}


void printTable(char *fileName, Process pTable[MAX], int numLines)
{
    FILE *fileOUT = fopen(fileName,"w+");

    for(int i=0; i < numLines;i++)
    {
        fprintf(fileOUT, "%d %d %d\n",pTable[i].pid,
        pTable[i].arrTime, pTable[i].burTime);
    }
}

int main(int argc, char **argv)
{
    int linesProcessed = readTable(argv[1], pTable);
    printTable(argv[2], pTable, linesProcessed);
}
Community
  • 1
  • 1
Dumbo
  • 13,555
  • 54
  • 184
  • 288
  • what if the max value varies? like another max number could be used, I just want to scan and allocate enough memory for the scanned lines. I'm receiving a segmentation fault with the corrected code. – Brad Van Buren Oct 10 '16 at 00:14
  • @BradVanBuren The code works for me, maybe you can upload your input file somewhere which I can test with? The idea with the MAX is you pick an arbitrary large number which always is bigger than your expected lines in the data file. – Dumbo Oct 10 '16 at 06:48