Reputation: 61
I was wondering how I'd add data I've read from a CSV file into a Struct (would a Struct even be the best way to go?). My CSV file is just 4 values under a header (x,y,u,v). The plan would be to store the data (without the header), and then manipulate it and/or perform calculations with it. The file reads fine, I'm just confused what to do with it, once it's opened.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/time.h>
#include <string.h>
#include "tasks.h"
typedef struct {
float xvalue;
float yvalue;
float uvalue;
float vvalue;
} flow_data;
int main(int argc, char *argv[]) {
char* flow_file = NULL;
int resolution = 0;
flow_file = argv[2];
resolution = atoi(argv[3]);
// Reading flow_data.csv
FILE* flow_fileopen = fopen(flow_file, "r");
// Checking if the file has been read succesfully
if( flow_fileopen == NULL)
{
perror("Error opening file");
exit(1);
}
// Wasn't sure how to find the entry count, so I manually set it for now.
int entry_count = 7;
flow_data *dataset = malloc(sizeof(flow_fileopen) * entry_count);
char c;
do {
c = fgetc(flow_fileopen);
printf("%c", c );
} while (c != EOF);
free(dataset);
What the data set looks like
x y u v
1 2 3 4
2 3 4 5
Upvotes: 1
Views: 1366
Reputation: 31599
flow_data *dataset = malloc(sizeof(flow_fileopen) * entry_count);
flow_fileopen
is a pointer and sizeof(flow_fileopen)
is just the size of pointer (4 or 8 for example). You want sizeof(flow_data)
instead. You can also use sizeof(*dataset)
which maybe less prone to typing error.
Once you allocate enough memory, you can use fscanf
to read each line, and save to the structure. If fscanf
is successful, it returns the number of fields it reads. Make sure you skip the first line which holds the field names "x y u v".
int entry_count = 7;
flow_data* dataset = malloc(sizeof(*dataset) * entry_count);
//skip the first line which includes field names
char buf[500];
fgets(buf, sizeof(buf), flow_fileopen);
int total = 0;
while(1)
{
flow_data* p = &dataset[total];
if(4 != fscanf(flow_fileopen, "%f %f %f %f\n",
&p->xvalue, &p->yvalue, &p->uvalue, &p->vvalue))
break;
total++;
if(total == entry_count)
break; //this array can only hold a maximum of `entry_count`
}
Instead of guessing how many lines there are in the file, use realloc
to increase the size of the array as needed.
int main()
{
FILE* fp = fopen("flow_data.csv", "r");
if(fp == NULL)
{
perror("Error opening file");
exit(1);
}
char buf[500];
fgets(buf, sizeof(buf), fp); //skip the first line
int total = 0;
flow_data d;
flow_data* dataset = NULL;
while(4 == fscanf(fp, "%f %f %f %f\n", &d.xvalue, &d.yvalue, &d.uvalue, &d.vvalue))
{
dataset = realloc(dataset, sizeof(*dataset) * (total + 1));
dataset[total] = d;
total++;
}
for(int i = 0; i < total; i++)
{
flow_data* p = &dataset[i];
printf("%.1f, %.1f, %.1f, %.1f\n", p->xvalue, p->yvalue, p->vvalue, p->uvalue);
}
free(dataset);
return 0;
}
Upvotes: 2