简体   繁体   中英

How do I read data from a text file and store it in my C program to be used in functions?

I'm trying to read different data types on the same line of a text file, and currently trying to store them in their own arrays via a structure. I'm not sure if this is the best course of action to begin with, but the point is to read data from a file and manipulate it using different functions. I thought that if I could extract the data from the file and store it in arrays, I could send the arrays into functions with the arrays as their parameters. Here's what I have, and the problem explained within the main function:

Driver File:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "student_struct.c"

struct Student{
   char name[50];
   int id;
   float gpa;
   int age;
};

int main(){

FILE *fptr;
fptr = fopen("student_records.txt", "r");

if (fptr == NULL){
    printf("Error opening file!\n");
    exit(1);
}

struct Student students[100];
int i = 0;

while(!feof(fptr)){
    //PROBLEM HERE. Data for what is expected to be in the "gpa" array is always 0.
    fscanf(fptr, "%c %d %f %d", &students[i].name[i], &students[i].id, &students[i].gpa, &students[i].age);
    i++;
}

fclose(fptr);

//Always prints "0.0000"
printf("GPA of student #2: %f\n", students[1].gpa);
//avgGPA(students.gpa);

return 0;
}

Function:

#include <stdio.h>


float avgGPA(float gpa[]){

int i;

float avgGPA = 0;
for(i = 0; i < sizeof(*gpa); i++){
    avgGPA += gpa[i];
}
avgGPA = avgGPA / sizeof(*gpa);
printf("Average GPA: %f", avgGPA);

}

Text file:

David 1234 4.0 44
Sally 4321 3.6 21
Bob 1111 2.5 20
Greg 9999 1.8 28
Heather 0000 3.2 22
Keith 3434 2.7 40
Pat 1122 1.0 31
Ann 6565 3.0 15
Mike 9898 2.0 29
Steve 1010 2.2 24
Kristie 2222 3.9 46

My question is, how do I properly pull the data from the file and use it in different functions? Thank you for your help.

The %c in fscanf needs to be changed to %s . Refer to the fscanf man page for what each of the conversion specifiers mean. Specifically:

s

Matches a sequence of non-white-space characters; the next pointer must be a pointer to character array that is long enough to hold the input sequence and the terminating null byte ('\\0'), which is added automatically. The input string stops at white space or at the maximum field width, whichever occurs first.

c

Matches a sequence of characters whose length is specified by the maximum field width (default 1); the next pointer must be a pointer to char, and there must be enough room for all the characters (no terminating null byte is added). The usual skip of leading white space is suppressed. To skip white space first, use an explicit space in the format.

In other words, %c by default only matches a single character. %s matches multiple non-white space characters (ie, colloquially a "word").

Other follow on questions you had:

  • but if the array in the structure "Student" is made of characters, why does it properly function with a string?

    • In C a string is defined as an array of characters terminated by a NUL (0).
  • At that end, why does that influence the rest of the operation?

    • %c will consume just one character. Which means the next modifier ( %d in this case) will try to match with the remaining part of the first word and fail.

Other best practices that are relevant should be applied. Specifically:

  1. Always check the return value of function calls. fscanf in particular for this case. If that were done you would be able to see that fscanf had failed to match most of the modifiers.
  2. while !feof is always wrong. A full explanation of that is not provided here but please refer to other SO answers such as this .
  3. Use a debugger to step through your code to help you examine the state of variables to better understand what the program is doing and where things go wrong.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM