Using structure in reading a file, calculating, and writing into another - c

I have an input data file called "TEST.txt". it contains id numbers, names, grades of three different exams of ten students. I'm trying to make a program that reads these input data, calculates the mean value of exams for each student, and writes again id numbers,names, averages, of students whose averages are >=45.5 into output file called "RESULT.TXT" using structures.
I think I am able to read my input data with the structure I defined. I want to know what can I do for finding the averages of exams (one,two, and three), setting the condition of writing average values, and writing ids,names, and averages into RESULTS.TXT.
Here is my code until now.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
typedef struct student{
char name[30];
int id;
int exam1;
int exam2;
int exam3;
}STUDENT;
int main(){
int sum=0;
int i=0;
double mean[10];
STUDENT test[10];
FILE *fRead;
fRead=fopen("TEST.txt","r+");
if((fRead=fopen("TEST.txt","r"))==NULL){
printf("File could not be opened\n");
}
while(!feof(fRead)){
fscanf(fRead,"%d%s%d%d%d",&(test[i].id),test[i].name,&(test[i].exam1),&(test[i].exam2),&(test[i].exam3));
printf("\n%s\n",test[i].name);
i++;
}
return 0;
}

the following code:
is one possible way to perform the desired function:
cleanly compiles
uses fscanf() properly
does not use undesireable functions like feof()
is appropriately commented
performs appropriate error checking
does not include unnecessary header files
will handle any number of students in the input file, including 0 students
and now the code
#include <stdio.h> // fopen(), fscanf(), fclose()
#include <stdlib.h> // exit(), EXIT_FAILURE
#define MAX_NAME_LEN (29)
struct student
{
char name[MAX_NAME_LEN+1]; // +1 to allow for NUL terminator byte
int id;
int exam1;
int exam2;
int exam3;
};
int main( void )
{
struct student test;
FILE *fRead = NULL;
FILE *fWrite = NULL;
if((fRead=fopen("TEST.txt","r"))==NULL)
{
perror("fopen for read of Test.txt failed");
exit( EXIT_FAILURE );
}
// implied else, fopen successful
if( (fWrite = fopen( "RESULT.TXT", "w" )) == NULL )
{
perror( "fopen for write of RESULT.TXT failed" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
while( 5 == fscanf(fRead,"%d %" MAX_NAME_LEN "s %d %d %d",
&(test.id),
test.name,
&(test.exam1),
&(test.exam2),
&(test.exam3)) )
{
printf("\n%s\n",test.name);
float sum = (float)test.exam1 + test.exam2 + test.exam3;
float mean = sum / 3.0f;
if( 45.5f < mean )
{
fprintf( fWrite, "%d %s %d %d %d %2.2f\n",
test.id,
test.name,
test.exam1,
test.exam2,
test.exam3,
mean );
} // end if
} // end while
fclose( fRead );
fclose( fWrite );
//return 0; == not needed when returning from 'main' and value is zero
} // end function: main

I have made a few changes to the code you have written,
1. I have used loop instead of array of structure, the constant defines the number of students to scan.
I have created an fOut pointer for RESULT.txt, which I opened in append mode.
I created a condition, where if mean > 45.5, the details of the students will be printed in RESULT.txt.
P.S. I checked the program with 1 input in test file. Test it with multiple line inputs, should work fine.
#include <stdio.h>
#include <stdlib.h>
//constant for number of students, can be changed according to requirement
#define numOfStudents 10
typedef struct student{
char name[30];
int id;
int exam1;
int exam2;
int exam3;
}STUDENT;
int main(){
double sum=0;
int i=0;
double mean;
STUDENT test;
FILE *fRead;
//File pointer for output
FILE * fOut;
//File for output in append mode
fOut = fopen("RESULT.txt", "a+");
fRead=fopen("TEST.txt","r+");
if(fRead == NULL)
{
printf("File could not be opened\n");
}
//check if the file is successfully opened for appending
if(fOut == NULL)
{
printf("File could not be opened for printing\n");
}
for(i; i < numOfStudents; i++)
{
fscanf(fRead,"%d%s%d%d%d",&(test.id),test.name,&(test.exam1), &(test.exam2), &(test.exam3));
//calculates mean
sum = test.exam1 + test.exam2 + test.exam3;
mean = sum / 3.0;
//Condition for mean to be printed to output file
if(mean > 45.5)
{
fprintf(fOut, "%d %s %d %d %d", (test.id),test.name, (test.exam1),(test.exam2),(test.exam3 ));
fprintf(fOut, "\n");
}
if(feof(fRead))
{
break;
}
}
fclose(fRead);
fclose(fOut);
return 0;
}

Related

Problem with fscanf not reading inputs correctly

I'm having problems using a fscanf function. It never reads it correctly and always results in blanks.
fscanf(f, " %[^;];%[^;];%d;%d;%d;%d;%[^;];%d;%[^\n]",
arr[i].loc1, arr[i].loc2, &arr[i].price, &arr[i].rooms,
&arr[i].bathroom, &arr[i].carpark, arr[i].type, &arr[i].area, arr[i].furnish);
The code above always outputs " 0 0 0 0 0". But when I try using a scanf and manually input one of the lines, it works perfectly.
The file it's reading from is a .csv file. Here is the contents:
Mont-Kiara;Kuala-Lumpur;1000000;2;2;0;Built-up;1000;Partly
Cheras;Kuala-Lumpur;310000;3;2;0;Built-up;1000;Partly
Kepong;Kuala-Lumpur;358000;3;3;0;Built-up;1000;Partly
Taman-Desa;Kuala-Lumpur;455000;2;2;0;Built-up;1000;Partly
Kepong;Kuala-Lumpur;358000;3;3;0;Built-up;1000;Partly
Kepong;Kuala-Lumpur;358000;3;3;0;Built-up;1000;Partly
And here is the full code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct houseData {
char loc1[101];
char loc2[101];
int price[101];
int rooms[101];
int bathroom[101];
int carpark[101];
char type[101];
int area[101];
char furnish[101];
} arr[1001];
int read() {
int i = 0;
struct houseData arr[800];
char temp1[100];
FILE *f = fopen("file.csv", "r");
while(!feof(f)){
fscanf(f, " %[^;];%[^;];%d;%d;%d;%d;%[^;];%d;%[^\n]"
, &arr[i].loc1, &arr[i].loc2, &arr[i].price, &arr[i].rooms,
&arr[i].bathroom, &arr[i].carpark, &arr[i].type, &arr[i].area, &arr[i].furnish);
i++;
}
fclose(f);
}
int main() {
read();
printf("%s %s %d %d %d %d %s %d %s", arr[i].loc1, arr[i].loc2, *arr[i].price, *arr[i].rooms, *arr[i].bathroom, *arr[i].carpark, arr[i].type, *arr[i].area, arr[i].furnish);
return 0;
}
There are a lot of issues in your code. Here's a version that may help. The error messages in this version are far from ideal (this does not distinguish between an input format error and a error reading data, for example, nor does it provide much detail on the location of the error), and there is still the possibility of undefined behavior on certain inputs, (see Is `scanf("%d", ...)` as bad as `gets`?) but this should point you in the right direction. Well, at least it may help to improve your use of scanf, but a very reasonable argument can the be made that the "right direction" is to stop using scanf completely. It is very difficult to get things right with scanf, and attempting to do so winds up being much more complex that just using fgets. But for simple use cases it is ... still pointless to use scanf. See http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html and many other resources that explain why scanf is a terrible choice.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct houseData{
char loc1[101];
char loc2[101];
int price;
int rooms;
int bathroom;
int carpark;
char type[101];
int area;
char furnish[101];
};
int
read(FILE * f, struct houseData *h)
{
return 9 == fscanf(f, " %100[^;]; %100[^;]; %d; %d; %d; %d; "
"%100[^;]; %d; %100[^\n]", h->loc1, h->loc2, &h->price,
&h->rooms, &h->bathroom, &h->carpark, h->type, &h->area,
h->furnish);
}
int
main(int argc, char **argv)
{
int rv;
FILE *f = argc > 1 ? fopen(argv[1], "r") : stdin;
if( f == NULL ){
perror(argv[1]);
return EXIT_FAILURE;
}
struct houseData h;
int i = 0;
while( read(f, &h) ){
printf("%d: %s %s %d %d %d %d %s %d %s\n", ++i,
h.loc1, h.loc2, h.price, h.rooms, h.bathroom,
h.carpark, h.type, h.area, h.furnish);
}
if( ! feof(f) ){
fprintf(stderr, "Error near line %d\n", i);
}
fclose(f);
}

Floating point exception (core dumped) while creating a C program for Linux

I am new to C and need some help, when I execute this code, the output shows "Floating point exception (core dumped)" instead of a number which I don't know what it could be. I don't really know what is wrong with my code since I am a total beginner with Linux and C. Every help is appreciated.
Here is my functions.c:
#include "header.h"
int count(FILE *file){
int count=0,n;
char word[WORDS];
while(fscanf(file,"%s",word)==1 ){
count++;
};
return count;
};
int total(FILE *file){
int numbers, sum=0;
int token;
while(token!=EOF){
token=fscanf(file,"%d",&numbers);
sum+=numbers;
};
return sum;
};
and here is my main.c:
#include "header.h"
int main(){
char word[WORDS];
char theFile[WORDS];
FILE *fileptr;
printf("Enter the file name: ");
scanf("%s",theFile);
printf("Reading file %s...\n", theFile);
fileptr=fopen(theFile,"r");
if(fileptr==NULL){
fprintf(stderr,"ERROR: The file '%s' does not exist\n", theFile);
return 1;
};
int theSum=total(fileptr);
int theCount=count(fileptr);
int theMean= theSum/theCount;
printf("Average weight: %d \n", theMean);
return 0;
};
The main reason for getting Floating point exception is that you are accessing the file beyond its size.
In function total and count you are using the same pointer, so when done with total the file pointer is at the end of file, and you are using the same in count also.
you need to do fseek(file,SEEK_SET,0);, to make the pointer point at the beginning.
and all of you block statements and functions are end by ;, thats wrong.
I have corrected the program as a whole assuming that the contents of the file are just numbers like this 1 2 3 4 5 6
#include <stdio.h>
#define WORDS 100
int count(FILE *file){
int count = 0,n;
char word[WORDS];
// you need this to access the elements from start of the file
// comment below line causes sigfpe, Floating point exception
fseek(file,SEEK_SET,0);
printf(" position of fptr in count = %d\n",ftell(file));
while(fscanf(file,"%s",word)==1 ){
count++;
}
return count;
}
int total( FILE *file ){
int numbers, sum = 0;
int token;
// This is checked after number is read, will add the last number 2 times
//while(token != EOF){
while(1)
{
token = fscanf(file,"%d",&numbers);
printf("N = %d, token = %d\n", numbers, token);
if(token == EOF )
break;
sum += numbers;
}
printf(" position of fptr in total at the end = %d, sum = %d\n",ftell(file), sum);
return sum;
}
int main(){
char word[WORDS];
char theFile[WORDS];
FILE *fileptr;
printf("Enter the file name: ");
scanf("%s",theFile);
printf("Reading file %s...\n", theFile);
fileptr=fopen(theFile,"r");
if(fileptr == NULL){
fprintf(stderr,"ERROR: The file '%s' does not exist\n", theFile);
return 1;
}
int theSum = total(fileptr);
int theCount = count(fileptr);
//make sure to add a check that `theCount` is not zero
int theMean = theSum/theCount;
printf("Average weight: %d \n", theMean);
return 0;
}
In this statement
int theMean= theSum/theCount;
when theCount is 0 you are dividing by zero, which is undefined behavior and is probably causing the FPE.

Save just the second element of each line from a file into a vector in c

I have this function that saves in an integer variable all the numbers from a text file. But I want to make a change so that I can save just the second number in each line into a vector and then print the whole vector. Here is an example of the file.txt:
123 19
321 18
432 9
876 16
875 17
And here is the code that must be changed:
void LerVetor(int *V, int *N)
{
FILE *fp;
int marks;
fp = fopen("dados3.txt", "r");
if (fp == NULL)
printf("Falha ao abrir ficheiro\n");
rewind(fp);
do
{
fscanf(fp, "%d", &marks);
printf("%d\n", marks);
} while (!feof(fp));
fclose(fp);
}
The output is the same as the file.txt because the code just prints the content of the file.
Resume: Save just the second numbers of each line, ex: 19, 18, 9..., in a vector and then print the vector.
the following proposed code:
cleanly compiles
groups the variables with where they are used
properly checks and handles I/O errors
read/displays the second number from each line of the file
performs the desired functionality
and now, the proposed code:
#include <stdio.h>
#include <stdlib.h>
void LerVetor( void )
{
FILE *fp = fopen("dados3.txt", "r");
if( !fp )
{
perror("fopen to read: dados3.txt failed");
exit( EXIT_FAILURE );
}
int marks;
int dummy;
while( fscanf(fp, "%d %d", &dummy, &marks) == 2 )
{
printf("%d\n", marks);
}
fclose(fp);
}
One way you can do it is to pass a pointer to the vector (array of ints) where you need to store the values as a parameter of the function.
To dispose the first value in every line you can use a discard specifier %*d:
Live sample
#include <stdio.h>
void LerVetor(int* vector)
{
FILE *fp;
if (!(fp = fopen("dados3.txt", "r"))){
perror("Falha ao abrir ficheiro"); //print eventual open file error
return;
}
// keep reading lines discarding first value with %*d avoiding container overflow
for(int i = 0; fscanf(fp, "%*d %d", &vector[i]) == 1 && i < 100; i++)
printf("%d\n", vector[i]); //printing vector values
fclose(fp);
}
int main(void)
{
int vector[100];
LerVetor(vector);
return 0;
}

***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!!*****
The following proposed code:
cleanly compiles
cleans up after it self (in this case closes the input file
checks for and handles errors
outputs error messages to stderr rather than stdout
exits when a problem is incountered
does not contain 'magic' numbers. I.E. the hard coded '5'
reads up to 5 lines from the input file, instead of just one line
corrects the (several) syntax errors in the posted code
preforms the desired functionality
still uses fscanf() although a better call would be fgets() as that would eliminate the code block containing getc()
eliminates unneeded local variables
uses the correct signature for the main() function
documents why each header file is included
follows the axiom: only one statement per line and (at most) one variable declaration per statement.
keeps variable declaration local to where it is being used.
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
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.
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;

Saving struct to a file in C

In my assignment I was given two functions to write
int openFileFromConsole(FILE *fp)
It takes an empty file pointer as input to the function using call by reference. And updates the pointer to point to the appropriate HDD address. IMPORTANT: Later, it asks the user through the console to provide the name and also asks for the file open type: "w", "r", "a" and UPDATES the file pointer. It returns 1 if succeeded, or 0 if fails.
void saveStudentGradeInfoTofile(FILE *fp)
This function gets the student info and saves it first into the student data-type (which is struct but disguised using typedef) then saves it to file. The student information is being provided by the register through the console. This takes the file pointer by reference as input and update the file using fprint.
This program is supposed to open a file through console depending on the user input then collect information and store them to a struct and save it to that file.I have written the two functions(correctly I think?).But I am having a hard time implementing them to main() since the first one is an int type function.Any help would be appreciated.
typedef struct student {
char name[50];
char id [20];
int score;
}student;
int openFileFromConsole(FILE *fp);
void saveStudentGradeInfoTofile(FILE *fp);
int main()
{
return 0;
}
int openFileFromConsole(FILE *fp){
char filePath[100],fileOpenType[10];
printf("Enter Path name: ");
scanf("%s", filePath);
printf("Enter file open type w, r or a: ");
scanf("%s", fileOpenType);
fp = fopen(filePath,fileOpenType);
if(fp != NULL) {
printf("File has been opened");
return 1;
}
else printf("File not found");
return 0;
}
void saveStudentGradeInfoTofile(FILE *fp){
int numOfStudent ;
student s[100];
printf ("Get the number of students :");
scanf("%d",&numOfStudent);
for(int i = 0; i < numOfStudent; i++) {
printf("\nEnter ID number:");
scanf(" %s",s[i].id);
printf("Enter name: ");
scanf("%s,",s[i].name);
printf("Enter score: ");
scanf("%d",&s[i].score);
fprintf(fp,"id : %s, Name: %s, score =%d\n",s[i].id,s[i].name,s[i].score);
printf("\n");
}
}
the posted code has a few problems.
it does not follow the axiom: only one statement per line and (at most) one variable declaration per statement. The result is the code is much more difficult to understand, debug, maintain.
The calls to system functions need to have their returned values checked to assure the operation was successful.
To modify where a pointer, located in the calling function, points, the pointer must be passed as a 'pointer to a pointer'.
when calling any of the scanf() family of functions, when using the '%s' input conversion specifier, always include a MAX CHARACTERS modifier that is 1 less than the length of the input buffer, so the user cannot overrun the input buffer. Such overrun results in undefined behavior and can lead to a seg fault event.
when using the '%s' input conversion specifier, insert a space before the specifier to consume any leading 'white space', like any newline sequence.
always cleanup when exiting a program. Do not leave the cleanup to the OS.
when working with numeric values that will never be less than 0, it is best to use size_t rather than int
The posted code is never reading from the student grade info file, so should never be opened with r
the 'mode' in a call to fopen() is always a string, even if it is only a single char, so needs to be written as "w" not just a w
the code contains lots of 'magic' numbers. 'magic' numbers are numbers with no basis. Such numbers make understanding, debugging, etc much more difficult than necessary. Suggest using an enum statement or #define statements to give those 'magic' numbers meaningful names, then use those meaningful names throughout the code.
for ease of readability and understanding, consistently indent the code. indent after every opening brace '{'. unindent after every closing brace '}'. Suggest using 4 spaces for each indent level as that is visible even with variable width fonts.
it is a poor programming practice to combine a 'struct' definition with a 'typedef'. code them separately.
when posting code, include the needed header file statements, so we do not have to guess what your code actually uses.
for ease of readability and understanding, separate code blocks (for, if, else, while, do...while, switch, case, default) via a single blank line. Separate functions by 2 or 3 blank lines (be consistent).
While modern compilers will handle the duplication of names, as modern compilers keep the struct names in a separate namespace from the typedef names, it is a poor programming practice that easily leads to confusion. Suggest keeping names unique (although that was not followed in this answer.
Here is a possible implementation of the desired functionality:
#include <stdio.h> // fopen(), fclose(), perror(), FILE
#include <stdlib.h> // exit(), EXIT_FAILURE
enum {
MAX_NAME_LEN =50,
MAX_ID_LEN =20,
MAX_PATH_LEN =100,
MAX_TYPE_LEN =10,
MAX_NUM_STUDENTS =100
};
struct student
{
char name[ MAX_NAME_LEN ];
char id [ MAX_ID_LEN ];
int score;
};
typedef struct student student;
int openFileFromConsole(FILE **fp);
void saveStudentGradeInfoTofile(FILE *fp);
int main( void )
{
FILE * fp = NULL;
int openStatus = openFileFromConsole(&fp);
if( 0 == openStatus )
{
saveStudentGradeInfoTofile( fp );
}
fclose( fp );
return 0;
} // end function: main
int openFileFromConsole(FILE **fp)
{
char filePath[ MAX_PATH_LEN ];
char fileOpenType;
printf("Enter Path name: ");
if( 1 != scanf("%100s", filePath) )
{
perror( "scanf for file path failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
printf("Enter file open type w, r or a: ");
if( 1 != scanf(" %c", &fileOpenType) )
{
perror( "scanf for file open type failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
char buffer[ MAX_TYPE_LEN ];
buffer[0] = '\"';
buffer[1] = fileOpenType;
buffer[2] = '\"';
buffer[3] = '\0';
*fp = fopen(filePath, buffer);
if( *fp )
{
return 1;
}
else
{
perror( "fopen failed" );
return 0;
}
} // end function: openFileFromConsole
void saveStudentGradeInfoTofile(FILE *fp)
{
size_t numOfStudent;
student s[ MAX_NUM_STUDENTS ];
printf ("Get the number of students :");
if( 1 != scanf("%lu",&numOfStudent) )
{
perror( "scanf for number of students failed:" );
fclose( fp );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
for( size_t i = 0; i < numOfStudent; i++)
{
printf("\nEnter ID number:");
if( 1 != scanf(" %19s",s[i].id) )
{
perror( "scanf for student ID failed" );
fclose( fp );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
printf("Enter name: ");
if( 1 != scanf(" %49s,",s[i].name) )
{
perror( "scanf for student ID failed" );
fclose( fp );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
printf("Enter score: ");
if( 1 != scanf("%d",&s[i].score) )
{
perror( "scanf for student Score failed" );
fclose( fp );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
fprintf(fp,"id : %s, Name: %s, score =%d\n",
s[i].id,
s[i].name,
s[i].score);
printf("\n");
} // end while
} // end function: saveStudentGradeInfoToFile
Just in case you want to pass the file path as an argument to your program
int main(int c /* argument counter */, char *v[] /*argument list */)
{
FILE *fp;
if(c >= 2) {
char *path = v[1]; /* this is the second argument (the first one, v[0], is the program's name): ./foo myfile.txt */
fp = fopen(path, "your mode goes here");
/* ... */
}
}

Resources