Question

Anyone know how to read a text file into a struct array? I've been trying to figure out how to do so to no avail.

Here's the function header

int getRawData(FILE* fp, struct nameRecord records[], int currSize)

where the first parameter is passed a file already open for reading, the second an array of nameRecord structs, and the third the number of records currently in that array. The function is supposed to read the data from the file into the array placing it at the end of the array. It then returns the total number of records in the array after reading the file.

I'm also at a loss at initializing the number of elements for the nameRecord struct array. We've never been taught memory allocation and the problem doesn't make any mention of how many records are within the files, making initialization an excercise in frustration. So far, I'm taking advice from someone at another forum and using malloc, but I don't even really know what it does.

Some info on the program itself to provide context:

program will ask the user to enter a name (you may assume that the name will be no more than 30 characters long). It will then find the popularity of the name between 1921 and 2010 and print out a chart and graph. The program will then ask the user if they wish to do another analysis and repeat the process.

The program will pull information from the following data sources in determining the popularity of a name.

ontario female baby names ontario male baby names

Note that some names are considered both male and female so your program will needs the data from both files regardless of the name entered.

My attempt at the function:

//function that reads and places the read files into the struct arrays
    int getRawData(FILE* fp, struct nameRecord records[], int currSize) {
        int i;
        for(i = 0; i < currSize; i++) {
            fscanf(fp, "%[^,],%d,%d", records[i].name, &records[i].year, &records[i].frequency);
        }

And here's the entire program:

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

struct nameRecord {
    char name[31];
    int year;
    int frequency;
};
void allCaps(char[]);
int getRawData(FILE*, struct nameRecord[], int);
void setYearTotals(struct nameRecord, int, int);
void setNameYearTotals(char, struct nameRecord, int, int);
void getPerHundredThousand(int, int, double);
void printData(double);
void graphPerHundredThousand(double);

int main(void)
{
    int currSizem = 0;
    int currSizef = 0;
    struct nameRecord *records;
    FILE* fp = NULL;
    FILE* fp2 = NULL;
    char name[31];
    printf("Please enter your name: ");
    scanf("%30[^\n]", name);
    printf("your name is %s\n", name);

//opening both male and female name files and reading them in order to get the total number of records in the array
    fp = fopen("malebabynames.csv", "r");
    if (fp != NULL) {
        printf("file opened\n");
        while(3 == fscanf(fp, "%[^,],%d,%d", records[currSizem].name, &records[currSizem].year, &records[currSizem].frequency)) {
            currSizem++;
        }
    } else {
        printf("file failed to open\n");
    }
    if(currSizem > 0) {
        records = malloc(currSizem * sizeof(struct nameRecord));
    }

    fp2 = fopen("femalebabynames.csv", "r");
    if (fp != NULL) {
        printf("file opened\n");
        while(3 == fscanf(fp2, "%[^,],%d,%d", records[currSizef].name, &records[currSizef].year, &records[currSizef].frequency)) {
            currSizef++;
        }
    } else {
        printf("file failed to open\n");
    }
    if(currSizef > 0) {
        records = malloc(currSizef * sizeof(struct nameRecord));
    }

    return 0;
}

//function that automatically capitalizes the users inputted name
void allCaps(char s[]) {
    while(*s != '\0') {
        *s = toupper((unsigned char) *s);
        s++;
    }
}
//function that reads and places the read files into the struct arrays
int getRawData(FILE* fp, struct nameRecord records[], int currSize) {
    int i;
    for(i = 0; i < currSize; i++) {
        fscanf(fp, "%[^,],%d,%d", records[i].name, &records[i].year, &records[i].frequency);
    }
    return 0;
}
Was it helpful?

Solution

approximately as follows :

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

struct nameRecord {
    char name[31];
    int year;
    int frequency;
};

int getRawData(FILE*, struct nameRecord[], int);

int main(void){
    const char *MaleFilePath =   "malebabynames.csv";
    const char *FemaleFilePath = "femalebabynames.csv";
    int currSizem = 0;
    int currSizef = 0;
    FILE* mfp = NULL;
    FILE* ffp = NULL;
    struct nameRecord *recordsOfMale, *recordsOfFemale;

//opening both male and female name files and reading them in order to get the total number of records in the array
    mfp = fopen(MaleFilePath, "r");
    if (mfp != NULL) {
        int dummy;
        printf("file opened\n");
        //line count
        while(1 == fscanf(mfp, " %*[^,],%*d,%d", &dummy)){
            ++currSizem;
        }
    } else {
        printf("file(%s) failed to open\n", MaleFilePath);
        exit(EXIT_FAILURE);
    }
    if(currSizem > 0) {
        recordsOfMale = malloc(currSizem * sizeof(struct nameRecord));
        if(recordsOfMale == NULL){
            perror("malloc for Male records");
            exit(EXIT_FAILURE);
        }
    }
    rewind(mfp);
    if(currSizem != getRawData(mfp, recordsOfMale, currSizem)){
        fprintf(stderr, "I could not read a record for the specified number\n"
                        "at reading %s\n", MaleFilePath);
        exit(EXIT_FAILURE);
    }
    fclose(mfp);

    //Do something

    free(recordsOfMale);

    return 0;
}

//function that reads and places the read files into the struct arrays
int getRawData(FILE* fp, struct nameRecord records[], int currSize) {
    int i;
    for(i = 0; i < currSize; i++) {
        if(3!=fscanf(fp, " %[^,],%d,%d", records[i].name, &records[i].year, &records[i].frequency))
            break;
    }
    return i;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top