Reputation: 774
So I am trying to read in a file and store it into my data struct, but every time I run it it either reads in garbage data and my struct is filled with 0s. Any suggestions?
I have functions to check if the data is valid, because my struct cannot store data that it has already stored (e.g same port or vmn).
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
typedef struct DataType{
double timeOffset;
int vmn;
int port;
}Data;
void insertDataType(Data *Data, double timeOffset, int vmn, int port){
Data->timeOffset = timeOffset;
Data->vmn = vmn;
Data->port = port;
}
double returnTimeOffset(Data D){
assert(D.timeOffset != 0.0);
return D.timeOffset;
}
int returnVMN(Data D){
assert(D.vmn != 0);
return D.vmn;
}
int returnPort(Data D){
assert(D.port != 0);
return D.port;
}
bool vmnValid(Data *Data, int n, int vmn){
int i;
for(i = 0; i <= n; i++){
if(Data[i].vmn != 0){
if(Data[i].vmn == vmn){
printf("Invalid vmn %d: vmn already inserted \n", vmn);
return false;
}
}
}
return true;
}
bool timeValid(Data *Data, int n, double timeOffset){
int i;
for(i = 0; i <= n; i++){
if(Data[i].timeOffset != 0.0){
if(Data[i].timeOffset == timeOffset){
printf("Invalid timeOffset %2lf: timeOffset already used \n", timeOffset);
return false;
}
}
}
return true;
}
bool portValid(Data *Data, int n, int port){
int i;
for(i = 0; i <= n; i++){
if(Data[i].port != 0){
if(Data[i].port == port){
printf("Invalid port %d: port already in use\n", port);
return false;
}
}
}
return true;
}
int main(int argc, const char * argv[]){
int n = 0;
int i = 0;
char c;
FILE *file;
// Open file
file = fopen("connect1.in", "r");
if (file == NULL) {
fprintf(stderr, "Invalid input file \n");
exit(1);
}
// Get number of lines (n)
while((c = fgetc(file))!= EOF){
if(c == '\n'){
n++;
}
}
printf("n = %d \n", n);
// Create a strut DataType of size n
Data *storage;
storage = calloc(n, sizeof(struct DataType));
// Read and insert the data
double timeOffset;
int vmn;
int port;
printf("\n");
while(fscanf(file, "%lf,%d,%d,", &timeOffset, &vmn, &port != EOF)){
printf("%lf %d %d \n", timeOffset, vmn, port);
if(timeValid(storage, n, timeOffset)){
if(vmnValid(storage, n, vmn)){
if(portValid(storage, n, port)){
insertDataType(&storage[vmn], timeOffset, vmn, port);
}
}
}
}
printf("\n");
printf("\n");
printf("Storage:\n");
for(i = 0; i <= n; i++){
printf("%3d: %2lf %d %d \n", i, storage[i].timeOffset, storage[i].vmn, storage[i].port);
}
}
Upvotes: 0
Views: 74
Reputation: 154335
Change
// while(fscanf(file, "%lf,%d,%d,", &timeOffset, &vmn, &port != EOF)){
while(fscanf(file, "%lf,%d,%d,", &timeOffset, &vmn, &port) != EOF){
// or better
while (fscanf(file, "%lf,%d,%d,", &timeOffset, &vmn, &port) == 3) {
@suspectus is correct, add rewind(file);
// change
// char c;
int c;
Minor considerations:
Data *storage;
// storage = calloc(n, sizeof(struct DataType));
// I like the style
storage = calloc(n, sizeof(*storage));
// In a number of places, function do not change *Data, so use `const`
// Useful to now, at a glance, that *Data is unchanged
// and forces the compiler to warn otherwise.
// bool vmnValid(Data *Data, int n, int vmn){
bool vmnValid(const Data *Data, int n, int vmn) {
Upvotes: 1
Reputation: 17288
After counting the number of lines the file pointer must be reset to the start of the file again.
Use the rewind() call which resets the file position back to file start after the line counting loop:
rewind(file);
Upvotes: 1