user3619937
user3619937

Reputation: 85

import CSV into an array using C

i have a CSV file with ; separator. Data are double type e.g: 0.66985787869876;0.254886543778;475.36552366\n 0.454585787869854;0.484254886543755578;512.36552374\n

Updated code after the answer of CyberSpock. My problem seems to be the fgets that have (shows with printf) the first value only rather than the full line

#include <stdio.h>
#include <stdlib.h>
#include <math.h>



double LoadCSV(double *Tab[][100])
{

    char* token;
    double intermed;
    char* test;
    FILE *fp;
    fp = fopen("file.csv","r");
    char line[128];
    int i=0, j=0;

    while (fgets(line, sizeof(line), fp) != NULL)
    {
        for (token = strtok(line,";"); token != NULL ; token = strtok(NULL, ";"))
        {
            token=strchr(token, "\n") ;
            intermed=atof(token);
            printf("%f", intermed);
            *Tab[i][j]= intermed;
            i++;
        }
        printf("%f", *Tab[3][j]);
        j++;

    }

   //fclose(fp);
    return 0;
}

int main(){

double Tab[50][100]; //max fixed size
int k=0;
int l=0;

LoadCSV(Tab);
while (k< 4)
    {
    printf("Tab = %f", Tab[k][l]);
    k++;
    }


}

OLD POST The size of the input CSV can be different each time: one time 3 columns and another 46 columns.

Then I think that I can't use scanf like scanf(file, "%f";"%f";"%f", varA, varB, VarC); Because vars are fixed one time.

Although i try this code but i have a problem with the var named c:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

double TabInput[100]; //max fixed size

double LoadCSV()
{

   FILE *fp;
   int c;
   char cumulate[100];
   int i=0;


   fp = fopen("file.csv","r");

   if(fp == NULL)
   {
      perror("Error in opening file");
   }

   while(1)
   {

      c = fgetc(fp);
      if( feof(fp) )
      {
         break ;
      }
      if (c != ";" || c != "\n")
      {
        printf("%s",c);//*************PROBLEM C is an int
        strcat(cumulate, d);//********PROBLEM THERE

      }
      else
      {
          TabInput[i]= atof(cumulate); //str to double
          i++;
      }
        if (c == "\n")
        {
            break ;
        }

   }
   fclose(fp);

   //return(TabInput);
}

int main(){
int j=0;
LoadCSV();
while (j< 4)
    {
    printf("Tab = %f", TabInput[j]);
    j++;
    }


}

Thank's for your help. Best.

Upvotes: 1

Views: 5659

Answers (1)

AndersK
AndersK

Reputation: 36082

use strtok instead

char line[128];
fgets( line, sizeof(line), fp );
for (char* token = strtok( line, ";"); token != NULL; token = strtok(NULL, ";"))
{
  TabInput[i++] = atof(token);
}

So you read one line at a time and then parse the line using strtok.

EDIT:

strtok splits up the string line into several strings and returns pointers to \0 terminated strings. the only thing you need to do is to convert the string to float/double using atof. in each iteration of the for loop token will point to a new string in line.

In order to split a CSV file into rows and columns you could do something like this

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

#define MAXROWS 10
#define MAXCOLS 5

int main()
{
  int rowIndex = 0;
  double rows[MAXROWS][MAXCOLS] = {{0,0}};
  char line[128];
  char* token = NULL;
  FILE* fp = fopen("myfile.csv","r");
  if (fp != NULL)
  {
    while (fgets( line, sizeof(line), fp) != NULL && rowIndex < MAXROWS)
    {
      int colIndex = 0;
      for (token = strtok( line, ";"); token != NULL && colIndex < MAXCOLS; token = strtok(NULL, ";"))
      {
        rows[rowIndex][colIndex++] = atof(token);
      }
      rowIndex++;
    }
    fclose(fp);
  }

  for (int i = 0; i < rowIndex; ++i)
  {
    for (int j = 0; j < MAXCOLS; ++j)
      printf("%10.4lf", rows[i][j]);
    putchar('\n');
  }

  return 0;
}

Upvotes: 3

Related Questions