-1

I want to read a csv file, the content is like the following:

fruit  time  price
apple  2022  18
banana 2022  30
apple  2023  19
banana 2023  32

I want to sort out the categories and process each category as a separate dataframe like:

dataframe 1:
fruit  time  price
apple  2022  18
apple  2023  19

dataframe 2:
fruit  time  price
banana 2022  30
banana 2023  32

May I know how can I do this by using C++? Thank you.

inv inv
  • 19
  • 3
  • There are already several questions about reading csv data in C++ on this site, can you clarify how these were not helpful and which part of the process you are having trouble with? – Borgleader Jun 29 '22 at 04:13
  • I am new to C++. Sorry for the silly question. I want to print out the two different dataframe first and process them. The first thing is I want to do the filtering. However I do not know how to do this. I can read the csv in the following code: – inv inv Jun 29 '22 at 04:17
  • #include #include using namespace std; void read() { ifstream fin; string line; fin.open("my_file.csv"); while(!fin.eof()){ fin>>line; cout< – inv inv Jun 29 '22 at 04:17
  • This is basically asking us to write your code for you. What have you tried, and what is the first problem you run into? You will need to learn basic file io/reading csv files and how to create a datastructure to put your data in. – Pepijn Kramer Jun 29 '22 at 04:17
  • Read [this](https://stackoverflow.com/questions/1120140/how-can-i-read-and-parse-csv-files-in-c) to see different ways to read in a csv file: – doug Jun 29 '22 at 04:21

2 Answers2

0

To read a csv file, the code is as follows:

#include <iostream>
#include<fstream>
using namespace std;
void read()
{
    ifstream fin;
    string line;
    fin.open("my_file.csv");
    while(!fin.eof()){
            fin>>line;
            cout<<line<<" ";
            }
    }

int main()
{
    read();
    return 0;
}

Not sure how to do the filtering part.

inv inv
  • 19
  • 3
0

Here is a more complete example (note : don't use "using namespace std")

#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <cstdint>
#include <map>
#include <vector>
#include <set>

// content of your input file.
std::istringstream file_stream
{
"fruit  time  price\n"
"apple  2022  18\n"
"banana 2022  30\n"
"apple  2023  19\n"
"banana 2023  32\n"
};

// model a piece of fruit as a struct
struct fruit_info_t
{
    std::string name;
    std::uint32_t year;
    double price;
};

// overload to output a fruit_info_t
std::ostream& operator<<(std::ostream& os, const fruit_info_t& info)
{
    os << info.name << "\t\t" << info.year << "\t\t" << info.price;
    return os;
}

// this map type allows us to lookup fruits by name
using fruits_t = std::map<std::string, std::vector<fruit_info_t>>;

// class to help us organize and find fruits read from file
class Fruits
{
public:
    // Add a new entry into our little database
    void AddFruit(const fruit_info_t& fruit)
    {
        // new category 
        if (m_keys.find(fruit.name) == m_keys.end())
        {
            m_keys.insert(fruit.name);
            m_fruits.insert({ fruit.name,std::vector<fruit_info_t>{} });
        }

        m_fruits.at(fruit.name).push_back(fruit);
    }

    const auto& UniqueFruitNames() const noexcept
    {
        return m_keys;
    }

    const auto& GetFruits(const std::string& unique_fruit_name) const
    {
        // return a vector with all fruits that share the same name
        return m_fruits.at(unique_fruit_name);
    }

    // sort the unique fruit names alphabetically
    // and sort the fruits in the list first by name then year then price
    void Sort()
    {
        std::sort(m_keys.begin(), m_keys.end());

        for (auto& [key, fruits] : m_fruits)
        {
            std::sort(fruits.begin(), fruits.end(), [](const fruit_info_t& lhs, const fruit_info_t& rhs)
                {
                    if (lhs.name < rhs.name) return true;
                    if (lhs.year < rhs.year) return true;
                    if (lhs.price < rhs.price) return true;
                    return false;
                });
        }
    }

private:
    std::set<std::string> m_keys;
    fruits_t m_fruits;
};

auto load(std::istream& stream)
{
    Fruits fruits;
    std::string header;
    std::getline(stream, header);

    std::string name;
    std::string year;
    std::string price;

    while (stream >> name >> year >> price)
    {
        fruits.AddFruit({ name, std::stoul(year), std::stof(price) });
    }

    return fruits;
}

int main()
{
    // replace file_stream with std::ifstream from a real file. 
    // I used the string stream to have file in code so I could share the test.
    auto fruits = load(file_stream);
    
    // sort datab before output. 
    fruits.Sort();

    for (const auto& unique_fruit_name: fruits.UniqueFruitNames())
    {
        std::cout << "dataframe : " << unique_fruit_name << "\n";
        std::cout << "fruit\t\ttime\t\tprice\n";
        auto infos = fruits.GetFruits(unique_fruit_name);
        
        for (const auto& info : infos)
        {
            std::cout << info << "\n";
        }
    }

    return 0;
}
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19