1

enter image description hereI have a c++ code for CSV reading. It is supposed to read the rows in accordance with the input. But it is reading only the first element of the input element row and is going to the next row giving me a diagonal output

#ifndef CSVREADER_H
#define CSVREADER_H

#include <string>
#include <map>
#include <fstream>
#include <sstream>
#include <iostream>
#include <chrono>
#include <time.h>

class CsvReader
{
public:
    CsvReader(std::string fileName)
    : m_nextLine(""), m_nextUpdate(0), m_infile(fileName.c_str())
    {
        m_start = std::chrono::steady_clock::now();
        if(m_infile.is_open())
        {
            /* read type and name from file */
            std::string type, name;
            std::getline(m_infile, type); // type
            std::getline(m_infile, name); // name

            std::stringstream ssname(name);//##assigning to object?
            std::stringstream sstype(type);
            m_type.clear();
            while (!ssname.eof())
            {
                std::string n,t;
                std::getline(ssname, n, ',');
                if(!sstype.eof())
                {
                    std::getline(sstype, t, ',');
                }
                m_type.insert(std::pair<std::string, std::string>(n,t));
            }
            std::getline(m_infile, m_nextLine); // first
            m_nextUpdate = (m_nextLine.length() > 0) ? atoi(m_nextLine.c_str()) : INT_MAX;
        }
    }

    int getInt(const char * varName);
    char getChar(const char * varName);
    float getFloat(const char * varName);

private:
    void update(void);

    std::ifstream m_infile;
    std::string m_nextLine;
    std::chrono::steady_clock::time_point m_start;
    int m_nextUpdate;
    std::map<std::string, std::string> m_line;
    std::map<std::string, std::string> m_type;
};

#endif

//main

#include "csvreader.h"
#include <Windows.h>
using namespace std;

void printData(CsvReader *csvReader)
//printData(CsvReader *csvReader)
{
    cout << csvReader->getInt("var1") << '\t'
        << csvReader->getInt("var2") << '\t'
        << csvReader->getFloat("var3") << '\t'
        << csvReader->getFloat("var4") << '\t'
        << csvReader->getChar("var5") << '\t'
        << csvReader->getInt("var6") << endl;
}

int main()
{
    CsvReader *csvReader = new CsvReader("input.csv");
    Sleep(10);  cout <<  10 << '\t'; printData(csvReader);
    Sleep(210); cout <<  210 << '\t'; printData(csvReader);
    Sleep(20);  cout <<  20 << '\t'; printData(csvReader);
    Sleep(10);  cout <<  10 << '\t'; printData(csvReader);
    Sleep(510); cout << 210 << '\t'; printData(csvReader);
    Sleep(20);  cout <<  20 << '\t'; printData(csvReader);

     //int i = csvReader->getInt("var1");
     //cout<<i;}*/
    return 0;
}


//cpp defined

#include "csvreader.h"

void CsvReader::update(void)
{
    std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
    long long elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - m_start).count();

    /* Read new values if the time is elapsed*/
    if(elapsed >= m_nextUpdate)
    {
        if(m_nextLine.length() > 0)
        {
            /* parse this line elements */
            m_line.clear();
            std::stringstream ssline(m_nextLine);
            std::map<std::string, std::string>::iterator itr;
            for (itr = m_type.begin(); itr != m_type.end(); ++itr)
            {
                if(!ssline.eof())
                {
                    std::string element;
                    std::getline(ssline, element, ',');
                    m_line.insert(std::pair<std::string, std::string>(itr->first, element));
                }
                else
                {
                    std::cout << "Error: invalid number of elements" << '\n';
                }
            }

            /* set next timer value */
            std::getline(m_infile, m_nextLine);
            m_nextUpdate = (m_nextLine.length() > 0) ? atoi(m_nextLine.c_str()) : INT_MAX;
        }
    }
}

int CsvReader::getInt(const char * varName)
{
    update();
    return atoi(m_line[std::string(varName)].c_str());
}

char CsvReader::getChar(const char * varName)
{
    update();
    return m_line[std::string(varName)].c_str()[0];
}

float CsvReader::getFloat(const char * varName)
{
    update();
    return atof(m_line[std::string(varName)].c_str());
}

The nextUpdate is the line supposed to do the operation of reading the next element but after reading a complete row first

  • Can you provide a short example of what your file looks like and what you'd expect to end up with in the maps? – Retired Ninja Nov 10 '22 at 04:18
  • sure, it has few columns with first column representing the time in milliseconds and the rest are variables corresponding to the time column – Delwin Mathew Nov 10 '22 at 04:43
  • at 0 it was supposed to read 1 11 1.2365 5.69472 a 9 – Delwin Mathew Nov 10 '22 at 05:01
  • but it is reading 1 12 3.4949 -7.28382 b -21 – Delwin Mathew Nov 10 '22 at 05:02
  • The only reading I see in this code is where it reads the first two lines from the file, possibly adds the `name, type` for each column into the map, then reads one more line and does nothing with it. Is there code missing? – Retired Ninja Nov 10 '22 at 05:19
  • this is my header file, I'll add main too – Delwin Mathew Nov 10 '22 at 08:52
  • Total code n CSV is updated please have a look – Delwin Mathew Nov 14 '22 at 06:01
  • I saw the update a few days ago and to be completely honest it just doesn't make much sense to me. Any one of the get functions could cause a new line to be read and it's completely unpredictable. – Retired Ninja Nov 14 '22 at 06:48
  • According to the required logic, the timer and the print must work independently. Without any blocking call. When the required delay is reached, the corresponding line must be printed. – Delwin Mathew Nov 15 '22 at 04:06
  • Seems fine to me: https://godbolt.org/z/dqx74ffT4 If you're seeing something different on your system it's time for you to do some debugging. There's still nothing to stop it switching in the middle of one `printData` call. – Retired Ninja Nov 15 '22 at 05:47

0 Answers0