SORU
13 Temmuz 2009, PAZARTESİ


Nasıl ve C CSV dosyalarını okumak ayrıştırabilir miyim ?

Yük ve C CSV dosyası veri kullanmak istiyorum . Bu noktada gerçekten sadece virgülle ayrılmış bir çözümleyici (yani yeni çizgi ve virgül kaçan merak etme) olabilir. Ana gereken her yöntemi olarak adlandırılan bir sonraki satır için bir vektör döndürür satır satır bir çözümleyici.

Oldukça umut verici görünüyor hangi bir makale buldum: http://www.boost.org/doc/libs/1_35_0/libs/spirit/example/fundamental/list_parser.cpp

Hiç Boost Ruhu kullanmadım, ama denemek için istekli değilim. Ama eğer daha basit bir çözüm değil, eğer yok sadece bakan değilim.

CEVAP
13 Temmuz 2009, PAZARTESİ


Eğer virgül ve yeni satır kaçan umurunda eğer
VE tırnak (Eğer kaçış...) Eğer hiç virgül ve yeni satır gömebilirsiniz
kod (TAMAM 14 ->sadece üç sonra çizgileri Ama tüm dosyayı okumak) için sadece 15.

std::vector<std::string> getNextLineAndSplitIntoTokens(std::istream& str)
{
    std::vector<std::string>   result;
    std::string                line;
    std::getline(str,line);

    std::stringstream          lineStream(line);
    std::string                cell;

    while(std::getline(lineStream,cell,','))
    {
        result.push_back(cell);
    }
    return result;
}

Sadece bir satır temsil eden bir sınıf oluşturmak istiyorum.
Bu nesnenin içine akış:

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

class CSVRow
{
    public:
        std::string const& operator[](std::size_t index) const
        {
            return m_data[index];
        }
        std::size_t size() const
        {
            return m_data.size();
        }
        void readNextRow(std::istream& str)
        {
            std::string         line;
            std::getline(str,line);

            std::stringstream   lineStream(line);
            std::string         cell;

            m_data.clear();
            while(std::getline(lineStream,cell,','))
            {
                m_data.push_back(cell);
            }
        }
    private:
        std::vector<std::string>    m_data;
};

std::istream& operator>>(std::istream& str,CSVRow& data)
{
    data.readNextRow(str);
    return str;
}   
int main()
{
    std::ifstream       file("plop.csv");

    CSVRow              row;
    while(file >> row)
    {
        std::cout << "4th Element(" << row[3] << ")\n";
    }
}

Ama biraz çalışma ile teknik olarak bir yineleyici yaratabiliriz:

class CSVIterator
{   
    public:
        typedef std::input_iterator_tag     iterator_category;
        typedef CSVRow                      value_type;
        typedef std::size_t                 difference_type;
        typedef CSVRow*                     pointer;
        typedef CSVRow&                     reference;

        CSVIterator(std::istream& str)  :m_str(str.good()?&str:NULL) {   (*this); }
        CSVIterator()                   :m_str(NULL) {}

        // Pre Increment
        CSVIterator& operator  ()               {if (m_str) { (*m_str) >> m_row;m_str = m_str->good()?m_str:NULL;}return *this;}
        // Post increment
        CSVIterator operator  (int)             {CSVIterator    tmp(*this);  (*this);return tmp;}
        CSVRow const& operator*()   const       {return m_row;}
        CSVRow const* operator->()  const       {return &m_row;}

        bool operator==(CSVIterator const& rhs) {return ((this == &rhs) || ((this->m_str == NULL) && (rhs.m_str == NULL)));}
        bool operator!=(CSVIterator const& rhs) {return !((*this) == rhs);}
    private:
        std::istream*       m_str;
        CSVRow              m_row;
};


int main()
{
    std::ifstream       file("plop.csv");

    for(CSVIterator loop(file);loop != CSVIterator();  loop)
    {
        std::cout << "4th Element(" << (*loop)[3] << ")\n";
    }
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • fireflame65

    fireflame65

    27 Mart 2007
  • RD

    RD

    19 NİSAN 2006
  • TecnoTutosPC

    TecnoTutosPC

    19 Kasım 2012