Writing a file to a struct array - c

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;
}

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;
}

Related

Can anyone help? I am trying to read data from a file but its just spitting out garbage

I am trying to read from file hw4.data and see if it has a name. The user inputs the name via a command line argument. Everything works fine but I can't get the file to be passed between the functions correctly. The assignment requires that I define the file in main and pass it between SCAN and LOAD.
#include <stdio.h>
#include <stdlib.h>
struct _data {
char name[20];
long number;
};
int SCAN(FILE *(*stream)) { // skim through the file and find how many entries there are
int size = 0;
char s_temp[100];
long l_temp;
while (1) {
fscanf(*stream, "%s %ld", s_temp, &l_temp);
if (feof(*stream)) break;
size++;
}
return size;
}
struct _data* LOAD(FILE *stream, int size) { // loop through the file and load the entries into the main data array
struct _data* d = malloc(size * sizeof(struct _data));
int i;
for (i = 0; i < size; i++) {
fscanf(stream, "%s %ld", d[i].name, &d[i].number);
}
return d;
}
void SEARCH(struct _data *BlackBox, char* name, int size) { // loop through the array and search for the right name
int i;
int found = 0;
for (i = 0; i < size; i++) {
printf("%s %s\n", BlackBox[i].name, name);
if (strcmp(BlackBox[i].name, name) == 0) {
printf("*******************************************\nThe name was found at the %d entry.\n*******************************************\n", i);
found = 1;
break;
}
}
if (found == 0) {
printf("*******************************************\nThe name was NOT found.\n*******************************************\n");
}
}
void FREE(struct _data* BlackBox, int size) { // free up the dynamic array
free(BlackBox);
}
int main(int argv, char* argc[]) {
if (argv == 2) {
printf("The argument supplied is %s\n", argc[1]);
FILE* file = fopen("./hw4.data", "r");
int size = SCAN(&file);
struct _data* data = LOAD(&file, size);
SEARCH(data, argc[1], size);
fclose(file);
return 0;
} else {
printf("*******************************************\n* You must include a name to search for.*\n*******************************************\n");
return 0;
}
}
Here's the format of hw4.data
ron 7774013
jon 7774014
tom 7774015
won 7774016
A few issues:
In SCAN, remove the feof. Replace with: if (fscanf(*stream, "%s %ld", s_temp, &l_temp) != 2) break;
Note that after calling SCAN, you should do: rewind(file);. Otherwise, LOAD will only see [immediate] EOF.
And, as others have mentioned, just pass file to SCAN/LOAD and not &file.
Add a check for null return from fopen (e.g.) if (file == NULL) { perror("fopen"); exit(1); }
Stylistically:
If you have a comment describing a function, put it on the line above the function.
Try to keep lines within 80 chars
Here is the refactored code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct _data {
char name[20];
long number;
};
// skim through the file and find how many entries there are
int
SCAN(FILE *stream)
{
int size = 0;
char s_temp[100];
long l_temp;
while (1) {
if (fscanf(stream, "%s %ld", s_temp, &l_temp) != 2)
break;
size++;
}
return size;
}
// loop through the file and load the entries into the main data array
struct _data *
LOAD(FILE *stream, int size)
{
struct _data *d = malloc(size * sizeof(struct _data));
int i;
for (i = 0; i < size; i++) {
fscanf(stream, "%s %ld", d[i].name, &d[i].number);
}
return d;
}
// loop through the array and search for the right name
void
SEARCH(struct _data *BlackBox, char *name, int size)
{
int i;
int found = 0;
for (i = 0; i < size; i++) {
printf("%s %s\n", BlackBox[i].name, name);
if (strcmp(BlackBox[i].name, name) == 0) {
printf("*******************************************\n");
printf("The name was found at the %d entry.\n", i);
printf("*******************************************\n");
found = 1;
break;
}
}
if (found == 0)
printf("*******************************************\n"
"The name was NOT found.\n"
"*******************************************\n");
}
// free up the dynamic array
void
FREE(struct _data *BlackBox, int size)
{
free(BlackBox);
}
int
main(int argv, char *argc[])
{
if (argv == 2) {
printf("The argument supplied is %s\n", argc[1]);
FILE *file = fopen("./hw4.data", "r");
if (file == NULL) {
perror("fopen");
exit(1);
}
int size = SCAN(file);
rewind(file);
struct _data *data = LOAD(file, size);
SEARCH(data, argc[1], size);
fclose(file);
}
else
printf("*******************************************\n"
"* You must include a name to search for.*\n"
"*******************************************\n");
return 0;
}
Using realloc, we can combine SCAN and LOAD into a single function:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct _data {
char name[20];
long number;
};
// loop through the file and load the entries into the main data array
struct _data *
LOAD(FILE *stream, int *sizep)
{
struct _data *all = NULL;
struct _data *d;
int size = 0;
int capacity = 0;
while (1) {
if (size >= capacity) {
capacity += 10;
all = realloc(all,sizeof(*all) * capacity);
if (all == NULL) {
perror("realloc");
exit(1);
}
}
d = &all[size++];
if (fscanf(stream, "%s %ld", d->name, &d->number) != 2)
break;
}
// trim to size actually used
all = realloc(all,sizeof(*all) * size);
*sizep = size;
return all;
}
// loop through the array and search for the right name
void
SEARCH(struct _data *BlackBox, char *name, int size)
{
int i;
int found = 0;
for (i = 0; i < size; i++) {
printf("%s %s\n", BlackBox[i].name, name);
if (strcmp(BlackBox[i].name, name) == 0) {
printf("*******************************************\n");
printf("The name was found at the %d entry.\n", i);
printf("*******************************************\n");
found = 1;
break;
}
}
if (found == 0)
printf("*******************************************\n"
"The name was NOT found.\n"
"*******************************************\n");
}
// free up the dynamic array
void
FREE(struct _data *BlackBox, int size)
{
free(BlackBox);
}
int
main(int argv, char *argc[])
{
if (argv == 2) {
printf("The argument supplied is %s\n", argc[1]);
FILE *file = fopen("./hw4.data", "r");
if (file == NULL) {
perror("fopen");
exit(1);
}
int size;
struct _data *data = LOAD(file, &size);
SEARCH(data, argc[1], size);
fclose(file);
}
else
printf("*******************************************\n"
"* You must include a name to search for.*\n"
"*******************************************\n");
return 0;
}
I had to use rewind() in order to reset the file so that LOAD() would read from the start of the file and give good data.

How to print out contents of file in C using function?

I'm very noob in C, and also we are not allowed to use ftell() or something similar. I can't print out the contents of my file as it is asked from me.This is eventually task in which I should've created functions that reads contents of file and store it in array then returns number of items in file, and in main() I had to print out using readStations() function. In main() also there should've been railwayLine[100] array of type station.
File has text as follows:
1. 0.0 London-Kings-Cross*
2. 3.9 Finsbury-Park*
...
First of all, I created typedef struct called station with properties km and name which are the distance and name of stations. I've tried to create function readStations(char filename[20], station line[])
My attempt is as follows:
#include <stdio.h>
typedef struct {
char name[30];
double km;
} station;
int readStations(char filename[20], station line[]){
FILE* openedFile;
openedFile = fopen(filename, "r");
if(openedFile == NULL){
printf("Some problem occured with opening of file");
return 1;
}
station stations;
int count = 0;
for (; !feof(openedFile); count++){
fscanf(openedFile, "%lf %s", &stations.km, stations.name);
}
int numberOfStations = count;
return count;
}
int main(){
station railwayLine[100];
printf("");
}
Actually, it returns me the number of items of .txt file but in main I don't know how to print out all items as they look in .txt file.
This seems to meet your concerns. Note that the readStations() function is now told how many stations it can store. It also closes the file that was opened. The printStations() function prints the data.
#include <stdio.h>
typedef struct
{
char name[30];
double km;
} station;
static int readStations(char filename[], int max_line, station line[])
{
FILE *openedFile = fopen(filename, "r");
if (openedFile == NULL)
{
fprintf(stderr, "Some problem occurred opening the file %s\n", filename);
return 0;
}
int count;
for (count = 0; count < max_line; count++)
{
if (fscanf(openedFile, "%lf %s", &line[count].km, line[count].name) != 2)
break;
}
fclose(openedFile);
return count;
}
static void printStations(int num_stations, station line[])
{
for (int i = 0; i < num_stations; i++)
printf("%2d. %6.2f km - %s\n", i, line[i].km, line[i].name);
}
int main(void)
{
enum { MAX_STATIONS = 100 };
station railwayLine[MAX_STATIONS];
int num_stations = readStations("stations.txt", MAX_STATIONS, railwayLine);
printStations(num_stations, railwayLine);
}
Given input data (file stations.txt):
0.0 London-Kings-Cross*
3.9 Finsbury-Park*
The output is:
0. 0.00 km - London-Kings-Cross*
1. 3.90 km - Finsbury-Park*

how data can be read from a text file and stored as as a structure?

Let's call this file f1.txt and it has given attributes.
Student code
name
ID
and resident structure from another file let's call f2.txt will be read with the following attributes
ID
City
and residence will be asked from keyboard.
I tried to but gett stucked at some point
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student
{
int student_code;
char name[20];
char ID[20];
};
int main()
{
FILE *input_file;
struct student input;
input_file = fopen("f1.txt", "r");
if(input_file == NULL)
{
fprintf(stderr, "\nError!\n");
exit(1);
}
while(fread(&input, sizeof(struct student), 1, input_file))
printf("student code = %d name = %s ID = %s", input.student_code,
input.name, input.ID);
fclose(input_file);
return 0;
}
I'm new at C programming
for example f1.txt file will be in the following format
f1.txt
123456 yourname 987654
564566 test 454545
Use fscanf to read the lines because you know the format
Store the values into temporary variables
Copy them into a proper data structure: if you don't know the number of students use a dynamic array or a list.
EDIT:
Arrays allow random access, on the other hand lists only allow sequential access.
Here's my attempt using lists:
typedef struct student
{
int student_code;
char name[20];
char ID[20];
struct student* next;
}student_t;
typedef struct list_s
{
int size;
student_t* head;
student_t* tail;
} list_t;
void list_push_back(list_t* l, int code, char n[20], char id[20])
{
student_t* tmp = (student_t*)calloc(1,sizeof(*tmp));
tmp->student_code = code;
strncpy(tmp->name, n, 20);
strncpy(tmp->ID, id, 20);
if (l->head == NULL)
{
l->head = tmp;
l->tail = tmp;
l->size++;
return;
}
l->tail->next = tmp;
l->size++;
}
void list_print(list_t* l)
{
student_t* it = l->head;
while (it)
{
fprintf(stdout, "%d %s %s\n", it->student_code, it->name, it->ID);
it = it->next;
}
}
int main(int argc, char* argv[])
{
FILE *input_file;
struct student input;
input_file = fopen("f1.txt", "r");
if (input_file == NULL)
{
fprintf(stderr, "\nError!\n");
exit(1);
}
list_t* list = (list_t*)calloc(1,sizeof(*list));
char tmp_name[20];
char tmp_id[20];
int tmp_code = 0;
while (fscanf(input_file, "%d %s %s", &tmp_code, tmp_name, tmp_id) != EOF)
{
list_push_back(list, tmp_code, tmp_name, tmp_id);
}
fclose(input_file);
list_print(list);
return 0;
}
To read a single record into the structure input:
fscanf( input_file, "%d %s %s", &input.student_code, input.name, input.ID )
to read a integer and two strings into the relevant members.
fscanf() returns the number of formatted fields successfully assigned, so to display all records in the file in the manner your code attempts:
while( fscanf( input_file, "%d %s %s", &input.student_code,
input.name,
input.ID ) == 3 )
{
printf( "student code = %d, name = %s, ID = %s\n", input.student_code,
input.name,
input.ID ) ;
}

Saving a string from a text file to a struct using fscanf (C)

Sample Text file:
234765 PETER
867574 SMITH
I'm trying to take the id and string from the text file and save it into a struct. The id is saving fine but the string isn't.
typedef struct student
{
int id[DATA_SIZE];
char *student[DATA_SIZE];
}studentinfo;
studentinfo list;
struct student *create_space(int size)
{
struct student *tmp = (struct student*)malloc(size*sizeof(struct student));
return(tmp);
}
struct student * readData(struct student*pointer,studentinfo v)
{
int count =0;
int tmpid;
char str[256];
FILE* in_file;
in_file = fopen("studentlist.txt","r");
while(fscanf(in_file,"%d",&tmpid)!= EOF && count<DATA_SIZE)
{
fscanf(in_file,"%s",v.student[count]);
//printf("%s\n",str );
v.id[count]=tmpid;
count++;
}
pointer =&v;
return pointer;
}
int main()
{
struct student *data;
struct student *sdata;
data = create_space(1);
sdata = readData(data,list);
//printf("%s\n",sdata->student[2] );
}
Their are a couple of issues:
fscanf() reads formatted input, and returns the number of items read.
This line:
while(fscanf(in_file,"%d",&tmpid)!= EOF && count<DATA_SIZE)
Could be this:
while (count < DATA_SIZE && fscanf(in_file, "%d %255s", &list.id[count], str) == 2) {
Which verifies that 2 values are being read on each line successfully.
You are not checking if in_file returns NULL. It's safe to do this. This goes the same for malloc().
You need to correctly create space for char *students[DATA_SIZE], as this is an array of char * pointers. Once you allocate space for this via malloc() or strdup(), then you can copy the contents into students.
Here is an example of doing such a thing:
while (count < DATA_SIZE && fscanf(in_file, "%d %255s", &list.id[count], str) == 2) {
/* allocate space for one student */
list.student[count] = malloc(strlen(str)+1);
if (!list.student[count]) {
printf("Cannot allocate string\n");
exit(EXIT_FAILURE);
}
/* copy it into array */
strcpy(list.student[count], str);
count++;
}
Here is an example that you can use to help achieve your desired result:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DATA_SIZE 256
typedef struct {
int id[DATA_SIZE];
char *student[DATA_SIZE];
} studentinfo_t;
int main(void) {
FILE *in_file;
studentinfo_t list;
char str[DATA_SIZE];
size_t count = 0;
in_file = fopen("studentlist.txt", "r");
if (!in_file) {
fprintf(stderr, "%s\n", "Error reading file");
exit(EXIT_FAILURE);
}
while (count < DATA_SIZE && fscanf(in_file, "%d %255s", &list.id[count], str) == 2) {
list.student[count] = malloc(strlen(str)+1);
if (!list.student[count]) {
printf("Cannot allocate string\n");
exit(EXIT_FAILURE);
}
strcpy(list.student[count], str);
count++;
}
for (size_t i = 0; i < count; i++) {
printf("%d %s\n", list.id[i], list.student[i]);
}
return 0;
}

C Programming: Reading a file and storing in array of struct

I am trying to read a file test.txt via fscanf and store it in a array of struct. This is what I tried. Problem here is that fscanf is not working as it is supposed to. After reading the file, I am also trying to print it on screen, but it won't work.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Item {
double value;
int unit;
char name[50];
};
int load(struct Item* item, FILE* data);
void display(struct Item item, int variableA);
int main()
{
struct Item I;
int i;
char ck;
ck = fopen("test.txt", "r");
if (ck)
{
for (i = 0; i < 3; i++)
{
load(&I, ck);
display(I, 0); //DISPLAY FUNCTION THAT READS test.txt and DISPLAYS
}
fclose(ck);
}
return 0;
}
int load(struct Item* item, FILE* data)
{
fscanf(data, "%d,%.2lf,%s\n", &(*item).unit,&(*item).value,&(*item).name);
return 0;
}
void display(struct Item item, int variableA)
{
printf("|%3d |%12.2lf| %20s |***\n", item.unit, item.value, item.name);
return;
}
This is what I have in test.txt file:
205,11.20,John Snow
336,23.40,Winter is coming
220,34.20,You know nothing
Error: Program compiles with some warnings , but I get segmentation fault when I execute the code.
Any idea why?
Output Expectation: OUTPUT should be read from test.txt file and should be displayed on to the screen.
Multiple problems in the program:
1.
char ck;
ck = fopen("test.txt", "r");
fopen returns a FILE*, not a char, use
FILE* ck = fopen(...);
2.
fscanf(data, "%d,%.2lf,%s\n", &(*item).unit,&(*item).value,&(*item).name);
always check return value of fscanf, if it is smaller than the number of fields you requested, the following call to fscanf is unlikely to do what you expect. Also, *item.unit is the same as item->unit, use item->unit because it is shorter and cleaner:
int ret = fscanf(data, "%d,%lf,", &item->unit, &item->value);
if (ret != 3) { // error }
Third, %s matches a sequence of non-white-space characters, so when fscanf reads "John", it will stop, and the next fscanf call will get to read "Snow" while expecting an integer.
So to input a string with whitespace, use fgets instead, and remember to remove the newline character in the end.
Try following:
int main(void)
{
struct Item I;
int i;
FILE* ck;
int ret;
ck = fopen("test.txt", "r");
if (ck)
{
for (i = 0; i < 3; i++)
{
ret = load(&I, ck);
if (ret < 0)
break;
display(I, 0); //DISPLAY FUNCTION THAT READS test.txt and DISPLAYS
}
fclose(ck);
}
return 0;
}
int load(struct Item* item, FILE* data)
{
int ret = fscanf(data, "%d,%lf,", &item->unit, &item->value);
if (ret != 2) {
return -1;
}
fgets(item->name, sizeof item->name, data);
item->name[strlen(item->name)-1] = '\0';
return 0;
}
void display(struct Item item, int variableA)
{
printf("|%3d |%12.2lf| %20s |***\n", item.unit, item.value, item.name);
return;
}
It outputs:
$ ./a.out
|205 | 11.20| John Snow |***
|336 | 23.40| Winter is coming |***
|220 | 34.20| You know nothing |***
You can try this different approach.
It uses:
malloc,realloc to allocate and reallocate memory for array of structs. I assumed that much larger text files with more lines will be used and this allows the array to resize when needed to accommodate more information.
strtok to parse each peice of data between , delimeters, and then store them into the array of structures.
Checks return value of pointers to avoid segmentation faults.
Uses fgets to read each line of the file into a string, from which we can parse ourselves afterwards.
This is the proposed code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NAMESTRLEN 50
#define INITSIZE 3
#define MAXSIZE 100
typedef struct {
int unit;
double value;
char name[NAMESTRLEN+1];
} item_t;
typedef struct {
item_t *items;
int numlines;
} allitems_t;
allitems_t *initialize_arraystructs(void);
void print_arraystructs(allitems_t *allitems);
void read_insert_items(FILE *filestream, allitems_t *allitems);
void check_ptr(void *ptr, const char *msg);
int
main(void) {
allitems_t *allitems;
FILE *fp;
fp = fopen("test.txt", "r");
if (fp == NULL) {
fprintf(stderr, "%s\n", "Error reading file!\n");
exit(EXIT_FAILURE);
}
allitems = initialize_arraystructs();
read_insert_items(fp, allitems);
print_arraystructs(allitems);
return 0;
}
void
read_insert_items(FILE *filestream, allitems_t *allitems) {
int count = 0;
char line[MAXSIZE];
char *unit, *value, *name;
size_t numitems = INITSIZE;
allitems->items = malloc(numitems * sizeof(item_t));
check_ptr(allitems->items, "Initial Allocation");
while (fgets(line, MAXSIZE, filestream) != NULL) {
unit = strtok(line, ",");
value = strtok(NULL, ",");
name = strtok(NULL, "\n");
if (count == numitems) {
numitems *= 2;
allitems->items = realloc(allitems->items, numitems * sizeof(item_t));
check_ptr(allitems->items, "Reallocation");
}
allitems->items[count].unit = atoi(unit);
allitems->items[count].value = atof(value);
strcpy(allitems->items[count].name, name);
count++;
allitems->numlines++;
}
}
allitems_t
*initialize_arraystructs(void) {
allitems_t *allitems;
allitems = malloc(sizeof(allitems_t));
check_ptr(allitems, "Initial Allocation");
allitems->items = NULL;
allitems->numlines = 0;
return allitems;
}
void
print_arraystructs(allitems_t *allitems) {
int i;
for (i = 0; i < allitems->numlines; i++) {
printf("%d,%.2f,%s\n",
allitems->items[i].unit,
allitems->items[i].value,
allitems->items[i].name);
}
}
void
check_ptr(void *ptr, const char *msg) {
if (!ptr) {
printf("Unexpected null pointer: %s\n", msg);
exit(EXIT_FAILURE);
}
}

Resources