Thread: Researching how to best import CSV and separate content

  1. #1
    Registered User
    Join Date
    Feb 2015
    Posts
    15

    Researching how to best import CSV and separate content

    I am looking for the best option for important a CSV into a 2d array of strings. I will discuss the whole assignment at the bottom, however, I am not looking for straight code copy or the specific answer to the whole thing.

    I am looking for how to import and separate each item from the CSV. the first portion of the CSV is a string (some name) and I wish to store this string into an array of strings.

    I then want to take the other entries (all ints) and put them into another 2d array.

    position 0,0 on array 1 and position 0,0 on array two will all relate to the same name.

    So my very specific direct question, how do I import a CSV file and use the comma as a delimiter to separate the info.

    my initial though was a bit stream or something like that, but, that makes it difficult to deal with the initial string. A link or suggestions into the preferred method for this would be good. Generic code is ok too if accompanied with an explanation so I can implement my own.

    Once I have a solid place to start (research) I will follow up with another post if I get stuck anywhere.

    Thanks in advance.

  2. #2
    Registered User
    Join Date
    Jan 2014
    Posts
    45
    A different approach:
    * Allocate storage for two arrays. One, an array of char (char[]), the other, an array of pointer to char (char *[]).
    * Copy the whole (line?) into the first array.
    * Transform the line into multiple strings by replacing each occurrence of the delimiter with the null character ('\0').
    * Store a pointer to the first character of each string in the second array.

  3. #3
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    839
    My idea now:
    Code:
    typedef struct CSV_CELL_
    {
      // How to treat item
      char format[5];
      void *data;
    } CSV_CELL;
    typedef struct CSV_LINE_
    {
      int count;
      int capacity;
      size_t size;
      CSV_CELL *buff;
    } CSV_LINE;
    typedef struct CSV_LIST_
    {
      int count;
      int capacity;
      size_t size;
      CSV_LINE *buff;
    } CSV_LIST;
    // Read your data in and set the format string as you go
    // Display your data or whatever
    // Write back your data if necessary
    Last edited by awsdert; 02-04-2015 at 03:47 PM. Reason: forgot an _

  4. #4
    Registered User
    Join Date
    Feb 2015
    Posts
    15
    Great input but I can't use structs. I'll have a chance once I'm not driving to review and see what I can use and ask questions.


    how would I process or get each line

  5. #5
    Registered User
    Join Date
    Jan 2014
    Posts
    45
    Consider reading about the getc and fgets functions in <stdio.h>.

  6. #6
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    839
    Well as CSVs are text files you can use FILE *file = fopen( path_to_csv, "r" ); and while( fgets( line, size_of_line, file ) ) to read the line, rest is just analysing the line based on CSV format (, or ; for seperators etc), you'll have to provide options somewhere for setting what separators and string tell-tales (", ', etc) to cope with different formats, unless it's a fixed file then options are pointless

  7. #7
    Registered User
    Join Date
    Feb 2015
    Posts
    15
    More good info. I will read up on all of the suggestions. Files are currently set formats. Seems fgets might be where I need to look.

    Thanks a million.

  8. #8
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    839
    You say you can't use structs? Just how old is your compiler? All modern ones will support C89 minimum (which includes struct support). I suppose you could do something like this:
    Code:
    #define CSV_CELL_FORMAT( CELL ) CELL
    #define CSV_CELL_BUFF( CELL ) ((void*)CELL[5])
    typedef char[ 5 + sizeof( void* ) ] CSV_CELL;
    #define CSV_LINE_COUNT( LINE ) ((int)LINE)
    #define CSV_LINE_CAPACITY( LINE ) ((int)LINE[sizeof(int)])
    #define CSV_LINE_SIZE( LINE ) ((size_t)LINE[sizeof(int)*2])
    #define CSV_LINE_BUFF( LINE ) ((CSV_CELL*)LINE[(sizeof(int)*2) + sizeof(size_t)])
    typedef char[ (2*sizeof(int)) + sizeof(size_t) + sizeof(void*) ] CSV_LINE;
    #define CSV_LIST_COUNT CSV_LINE_COUNT
    #define CSV_LIST_CAPACITY CSV_LINE_CAPACITY
    #define CSV_LIST_SIZE CSV_LINE_SIZE
    #define CSV_LIST_BUFF( LIST ) ((CSV_LINE*)LIST[(sizeof(int)*2) + sizeof(size_t)])
    typedef CSV_LINE CSV_LIST;
    If structs are unavailable to you
    Last edited by awsdert; 02-04-2015 at 04:40 PM. Reason: #define mistake

  9. #9
    Registered User
    Join Date
    Feb 2015
    Posts
    15
    It's a requirement from the instructor. We're playing with pointers and arrays. Structs are after the midterm.

  10. #10
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    839
    ah fair enough, best double check how safe my 2nd example is, I just threw it together off the top of my head, in a simple loop or whatever should be fine but if try to pass to another function might throw a compiler error, not sure.

  11. #11
    Registered Superuser nul's Avatar
    Join Date
    Nov 2014
    Location
    Earth
    Posts
    53
    There exists a function for just this purpose.

    strtok().

    If you are on a *nix system, go to your terminal and type "man 3 strtok".

  12. #12
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    839
    If you need a cross-platform safe version of it then this is my version:
    Code:
    char const* strntok (
      char       *dst,
      size_t      size,
      char const *src,
      char const *delim,
      char const *pos )
    {
      size_t i = 0;
      char const *d = delim;
    
      if ( !pos )
      {
        pos = src;
      }
    
      while ( *pos )
      {
        d = delim;
    
        while ( d[0] )
        {
          if ( *pos == d[0] )
          {
            ++pos;
            goto done;
          }
    
          ++d;
        }
    
        dst[i] = *pos;
        ++pos;
        ++i;
      }
    
      pos = NULL;
    done:
    
      if ( i < size )
      {
        dst[i] = 0;
      }
      else
      {
        dst[--i] = 0;
      }
    
      return pos;
    }

  13. #13
    Registered Superuser nul's Avatar
    Join Date
    Nov 2014
    Location
    Earth
    Posts
    53
    yea.... strtok is cross-platform.

    Don't recreate the wheel, poorly.

  14. #14
    Registered User
    Join Date
    Feb 2015
    Posts
    15
    Thanks guys looks like strtok() is the answer for this. Thanks!

  15. #15
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    For the general case of consuming CSV-format files, I tend to use two custom functions,
    Code:
    size_t csvfield(char **fieldptr, size_t *sizeptr, FILE *input);
    int csvnext(FILE *input);
    where the first one reads one field from the current record (line) using an interface similar to POSIX.1-2008 getline(), and the second one moves to the start of the next record (line), skipping any fields left in the current record (line) if any.

    The implementation uses fgetc() but also dynamic memory management via realloc(), so it's probably outside your current needs. However, it properly supports quoted and escaped contents, even those that include newlines, and has no line length or field length limits (besides the amount of memory that happens to be available at the time), so this approach works for all real-world CSV files.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Researching C++ - Your Opinions Wanted Here!
    By McCrockett in forum C++ Programming
    Replies: 2
    Last Post: 11-08-2012, 09:38 AM
  2. How to import DLL function from a separate C file
    By high123_98 in forum C++ Programming
    Replies: 7
    Last Post: 11-12-2011, 11:57 AM
  3. ASM dll import
    By borko_b in forum C Programming
    Replies: 1
    Last Post: 04-03-2003, 12:15 AM
  4. Import Dll
    By Shakespeare in forum C++ Programming
    Replies: 2
    Last Post: 01-27-2003, 05:40 AM
  5. NT Service - researching...
    By schu777 in forum Windows Programming
    Replies: 3
    Last Post: 03-25-2002, 02:58 PM

Tags for this Thread