Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17


Using ANSI C how to Read a .csv file

Posted on 2016-10-31
Medium Priority
Last Modified: 2016-11-01
I am using a bash shell script to parse a .csv file to create a text file that I read using ANSI C to fill some arrays.  I would like to learn how to read the .csv file just using C.  I only need the last 5 columns of the .csv file.  The .csv file has a one line descriptive header that needs to be skipped,  I have attached a modified version of the C code as well as the .csv file.
Question by:dwortman
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
LVL 20

Expert Comment

ID: 41867146
You could use a modified scanf to read the CSV entries.  Putting a "*" after the % in a match omits that bit of data.  You can also match the commas between the fields in the scanf string (no need to have spaces).

Reading directly from the csv file:
    fscanf(InputFile, "%*12[0-9/],%*d,%*3[A-Z],%*f,%*f,%*f,%f,%f,%f,%f,%f\n", &A_Array[i], &B_Array[i], &C_Array[i], 
									  &D_Array[i], &E_Array[i]);

Open in new window

The first field matches 12 characters of 0 to 9 or slash, matching the initial date field.  an alternative could be
Similarly, the %*3[A-Z] matches the timezone field.
The next three %*f miss out the next three floating point values.
The last 5 %f collect the values you want.

To skip the header line, you could have something like this, just before your "for i" loop:
    fscanf(InputFile, "%*s\n")
LVL 35

Expert Comment

ID: 41867222
fscanf is a dangerous function if you can't guarantee the input file is always valid.

you better read the file line by line and parse the input either by using strtok or by stepping from one delimiter to the next.

#include stdio.h

#define MAX_LINE 1024
#define MAX_TOKEN 256

int main(int nargs, char** szargs)
      FILE * pfile = NULL;
      char    buf[MAX_LINE] = { 0 };   // always use a sufficient maximum size 
      int nlines = 0;
      char * pbuf;

      if (nargs != 2) return -1;  //error no file path given
      pfile = fopen(szargs[1], "rt");
      if (pfile == NULL) return -2;  // file doesn't exist or already opened exclusively

      while (pbuf = fgets(buf, sizeof(buf), pfile))
             char * p = pbuf;
             int ntoken = 0;
             while ((p=strchr(p, ';')) != NULL || (p = strchr(p, '\n)) != NULL)
                   int     len = p - pbuf;
                   char  sztoken[MAX_TOKEN];
                   if (len >= MAX_TOKEN) return -3;  // token too Long
                   strncpy(sztoken, pbuf, len);
                   // do something with sztoken
                   // for example copy it into table[nlines][ntoken];
                   pbuf = p+1;
      return 0;        

Open in new window

note, the above is not tested.

LVL 40

Expert Comment

ID: 41867372
It's worth noting that parsing out CSV file is actually quite complicated because there are various different flavours of CSV and so you need to know how to correctly handle the flavour you are using. You'd probably be better of not re-inventing the wheel and using a purpose built library, such a libcsv.
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

LVL 20

Expert Comment

ID: 41867464
I guess there are potential problems with fscanf, but the only data being read here is floating point values - all that will happen with a malformed line is that the scanf will fail to match the line so will not return the value 11 (the number of matched fields).   Adding a check for a return code of 11 would be sensible here.  Problems tend to happen with strings, but the only 2 here are length-limited in the scanf format, and are anyway discarded. fscanf() also does the format conversion for you, so you don't have to add strtof() calls to convert the strings that strtok() returns.

The format seems to pretty simple here - no embedded quotes, not complex data structures, just simple values separated by commas. Using a library might be overkill (and some environments may have policies against using extra libraries), and rolling your own is often a useful learning exercise.

Author Comment

ID: 41868430

I like the way you are approaching this problem because I can basically understand it.  However, when I compile it I get the following errors:  (Please see attached file with my comments).

Author Comment

ID: 41868640
I found a syntax error in my code.  I need to check things out and will get back to close this ticket out.

LVL 20

Accepted Solution

simon3270 earned 2000 total points
ID: 41868666
Have you still got the backslash at the end of the first part of the line?  You don't need it (you are already within parentheses, you don't need to tell the compiler that the line hasn't finished!)  I think what's happened is that you have a space after the \ - if you have a \, it must be the last thing on the line.

As for the complaint about "]" in your comment, put [code] before the line of code, and [/code] after it.  I found that the easiest way when sending you the updated line.  An alternative would be to change all of the [i] to []i] - that stops the text interpreter from treating your [i] as an instruction to start using italics, and just treats it as a string of 3 characters.

(Edit - took me a while to write this comment so that the square brackets came out right - didn't spot that you'd already corrected it!)

Author Comment

ID: 41868735

The only problem now is that the 1st is not being skipped.  What you suggested to skip the first line looks like it should work.


Author Comment

ID: 41868914

I got it figured out.

Thanks for the help.

Author Closing Comment

ID: 41868915
Thanks for the help.

Featured Post


Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode ( They will have you believe that Unicode requires you to use…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question