Vin...C
Vin...C

Reputation: 1

***Reading from file in C*** using fscanf, Scanning and printing a char that doesn't exist in .txt file

Hello Everyone and Thank You for clicking!(Hate being stuck)

I'm trying to fscanf a char value from one file to a variable in my struct. When I scan I get a completely different letter than the one I'm trying to get. The problem is in my readfile function. If I get past this problem I hope I can scan numbers that I'll need to do arithmetic with is possible. My professor is teaching us FCFS (pertaining to OS scheduling algorithms not a FCFS data structure queue lesson). So the text files columns mean (PAS.txt):

Process Name | Arrival Time | Service Time

   A    0   3
   B    2   6
   C    4   4
   D    6   5
   E    8   2  

//Main.c
#include <stdio.h>
#include <time.h>
#include "lab8Func.h"


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

struct FCFS process;

readFile(&process);

printf("%s",&process.jobList[0].processName)

 }

//lab8func.h
#ifndef lab8Func_h
#define lab8Func_h
struct Job
{
    char processName;
    int arrivalTime;
    int serviceTime;
    int TAT;
    int NTAT;

};

struct FCFS
{
    struct Job jobList[5];

};

void readFile(struct FCFS*);

#endif /* lab8Func_h */

#include <stdio.h>
#include "lab8Func.h"


void readFile(struct FCFS *process1)
{  
FILE *file;
char temp;
int tempAT;
int tempST;



if((file = fopen("/Users/Vin/desktop/PAS.txt","r")) == NULL)
printf("Error, File Not Open.");
else
 {


    for(int i=0 ; i < 1; i++)
     {

         temp = fscanf(file," %c", &temp);  // where I'm stuck..
         process1->jobList[i].processName = temp;


        }


    }

}

OUTPUT

bProgram ended with exit code: 0 

***lowercase b ?? How ? I'm looking for capital A!!*****

Upvotes: 0

Views: 1149

Answers (3)

MFisherKDX
MFisherKDX

Reputation: 2866

Firstly, the return value of fscanf is the number of arguments successfully written (or EOF on failure). So you are overwriting your temp variable.

temp = fscanf(file," %c", &temp);

Secondly, this print statement is wrong:

printf("%s",&process.jobList[0].processName)

%s means to print a null terminated string and you are passing it a pointer to a char. They are both of type char * which is why it compiles, but they way you are calling can't be expected to work and may crash.

printf("%c",process.jobList[0].processName)

Thirdly, you are forgetting to read all three columns inside your loop with fscanf.

Upvotes: 2

user3629249
user3629249

Reputation: 16540

The following proposed code:

  1. cleanly compiles
  2. cleans up after it self (in this case closes the input file
  3. checks for and handles errors
  4. outputs error messages to stderr rather than stdout
  5. exits when a problem is incountered
  6. does not contain 'magic' numbers. I.E. the hard coded '5'
  7. reads up to 5 lines from the input file, instead of just one line
  8. corrects the (several) syntax errors in the posted code
  9. preforms the desired functionality
  10. still uses fscanf() although a better call would be fgets() as that would eliminate the code block containing getc()
  11. eliminates unneeded local variables
  12. uses the correct signature for the main() function
  13. documents why each header file is included
  14. follows the axiom: only one statement per line and (at most) one variable declaration per statement.
  15. keeps variable declaration local to where it is being used.
  16. makes some effort to improve the 'meaning' of the passed variable to the function: readFile()

Caveat: I modified the code layout (for my convenience) to all be in a single file

and now the proposed code:

#include <stdio.h>   // fopen(), fclose(), fscanf(), perror()
#include <stdlib.h>  // exit(), EXIT_FAILURE
//#include <time.h>
//#include "lab8Func.h"

//lab8func.h
#ifndef lab8Func_h
#define lab8Func_h

#define MAX_RECORDS 5

struct Job
{
    char processName;
    int  arrivalTime;
    int  serviceTime;
    int  TAT;
    int  NTAT;

};

struct FCFS
{
    struct Job jobList[ MAX_RECORDS ];
};

void readFile(struct FCFS*);

#endif /* lab8Func_h */



int main( void )
{
    struct FCFS jobs;

    readFile(&jobs);

    printf("%c", jobs.jobList[0].processName);
} // end function: main


void readFile(struct FCFS *jobs)
{
    FILE *file = NULL;

    if((file = fopen("/Users/Vin/desktop/PAS.txt","r")) == NULL)
    {
        perror( "fopen failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, fopen successful

    for(int i=0 ; i < MAX_RECORDS; i++)
    {
        char temp;
        if( 1 != fscanf(file," %c", &temp ) )
        { // handle error and exit
             perror( "fscanf failed" );
             fclose( file );  // cleanup
             exit( EXIT_FAILURE );
        }

        // implied else, fscanf successful

        jobs->jobList[i].processName = temp;

        // finish inputting the current line from the file
        int ch;
        while( (ch = getc( file ) ) != EOF && '\n' != ch )
        {
            ;
        }
    }

    fclose( file );   // cleanup
}  // end function:  readFile

Upvotes: 2

krpra
krpra

Reputation: 474

One thing should be kept in mind that you should always look at fscanf or scanf for checking if its returning true or false(any integer value or 0) i.e it is reading in correct format or not, and then process further.

You need to modify your code in for loop of readFile function:

   if((check=fscanf(file," %c", &temp))>0) 
      process1->jobList[i].processName = temp;

Upvotes: 0

Related Questions