0

I'm reading in data from a csv file that has some columns ending before others, i.e.:

0.01 0.02 0.01
0.02      0.02

And I'm trying to figure out how to catch these empty locations and what to do with them. My current code looks like this:

#include <iostream>
#include <fstream>
#include <sstream>
int main(){

//Code that reads in the data, determines number of rows & columns

//Set up array the size of all the cells (including empty):
double *ary = new double[cols*rows]; //Array of pointers
double var;
std::string s;
int i = 0, j = 0;

while(getline(data,line))
{
    std::istringstream iss(line);    //Each line in a string
    while(iss >> var)                //Send cell data to placeholder
    {
        ary[i*cols+j] = var;
        j+=1;
    }
    i+=1;
}

How can I determine if the cell is empty? I want to convert these to "NaN" somehow. Thank you!

JeJo
  • 30,635
  • 6
  • 49
  • 88
  • Is each number guaranteed to be of the form `X.XX`? Or will some have more digits? – scohe001 Apr 17 '18 at 23:25
  • Then you need to read each line per se then do some parsing. – Raindrop7 Apr 17 '18 at 23:26
  • 4
    That's not a CSV file. –  Apr 17 '18 at 23:26
  • @NeilButterworth: CVS files use comma as the separator. (comma separator values). – Raindrop7 Apr 17 '18 at 23:29
  • I was just posting an example of the data. It varies; looks like this: 9 0 0 12 0.0001 0.0001. @Raindrop7 how would I do that? I just found this and will look into it: https://stackoverflow.com/questions/1120140/how-can-i-read-and-parse-csv-files-in-c#1120224 –  Apr 17 '18 at 23:31
  • 2
    @Raindrop7 that might be part of the point Neil's trying to make, but CSV is much deeper than simply comma separated tokens these days. – user4581301 Apr 17 '18 at 23:32
  • It's a table in LibreOffice Calc that I saved as a .csv file, with the column delimiter being a tab. Regardless of the point, Neil your comment doesn't really help with anything –  Apr 17 '18 at 23:34
  • 1
    @Raindrop There are no commas in the user's data and it's "CSV", not "CVS". So I don't see what your point is. –  Apr 17 '18 at 23:35
  • First thing to do is to save it with delimiter being a comma - you will find that easier to read and to parse. –  Apr 17 '18 at 23:36
  • @wobertson do yourself a favour and build a simple wrapper structure around `double *ary` and it's indexing math. It'll make it a lot easier to pass around. Here is an example: https://isocpp.org/wiki/faq/operator-overloading#matrix-subscript-op By the way, good call on making a single array rather than an array of arrays. – user4581301 Apr 17 '18 at 23:38
  • Yo that looks like a good idea @user4581301, thanks for that –  Apr 17 '18 at 23:40
  • 2
    stream operator `>>` is blind to all forms of whitespace. A tab and a space all mean the same thing. It cannot detect an empty token for you. Look into `getline(iss, token, '\t')` and then converting var into a number. – user4581301 Apr 17 '18 at 23:41
  • @NeilButterworth I'll try that, I found an answer that talks about it: https://stackoverflow.com/questions/1120140/how-can-i-read-and-parse-csv-files-in-c#1120224, but what's wrong with using '\t' instead of ',' as the delimiter? Or, how does the comma help? –  Apr 17 '18 at 23:42
  • Ahhhhh okay @user4581301 that answers my previous question. Okay thanks! –  Apr 17 '18 at 23:43
  • Why comma is better wraps around to the same sort of problem as `>>`. At a glance you can distinguish commas from spaces, but you can't necessarily distinguish tabs from spaces. The computer doesn't care, they have different numeric values, but the human eye is easily fooled. – user4581301 Apr 17 '18 at 23:55

1 Answers1

1

You can do something like follows. Get the inputs, line by line and using (std::getline(sstr, word, ' ')) you can set the deliminator to ' ' and the rest is checking weather the scanned word is empty or not.

If it's empty, we will set it to NaN(only once).

Input:
0.01 0.02 0.01
0.02      0.02
0.04      0.08

Here is the output: enter image description here

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>

int main()
{
    std::fstream file("myfile.txt");
    std::vector<std::string> vec;

    if(file.is_open())
    {
        std::string line;
        bool Skip = true;

        while(std::getline(file, line))
        {
            std::stringstream sstr(line);
            std::string word;

            while (std::getline(sstr, word, ' '))
            {
                if(!word.empty())
                    vec.emplace_back(word);

                else if(word.empty() && Skip)
                {
                    vec.emplace_back("NaN");
                    Skip = false;
                }
            }
            Skip = true;
        }
        file.close();
    }

    for(size_t i = 0; i < vec.size(); ++i)
    {
        std::cout << vec[i] << " ";
        if((i+1)%3 ==0) std::cout << std::endl;
    }
    return 0;
}
JeJo
  • 30,635
  • 6
  • 49
  • 88