CSV用c ++解析

时间:2014-08-10 01:27:58

标签: c++ parsing csv

我正在尝试创建一个代码,该代码将使用库存信息解析csv数据库。目前,我已经生成了代码,因此它将使用关键字进行搜索并打印整行,但我试图获取它,以便它以整齐格式化的方式打印带有标题行的整行。 / p>

我试图获取它,以便在我搜索Google时,它会返回

  

符号GOOG      NAME Google Inc
     今日高位$ 568.77

csv如何:

  

符号,名称,价格,今日高位,今日低位,52周低位      GOOG,谷歌公司,568.77美元,570.25美元,560.35美元      AAPL,Apple Inc。,93.28美元,63.89美元,99.44美元。

代码:

string NameSearch::getInput()
{
    cout << "Enter the name of the company you would like to search for: ";
    getline(cin, input);
    return input;

}
void NameSearch::NameAlgorithm()
{
    string line;
    ifstream fs("Stock Database.csv");

    while (!fs.eof())
    {
        getline(fs, line);
        string companyname = "";    
        string a;
        int column = 1;             
        int commacount = 0;         
        int ChrCount = 0;               

        while (line != "\0")        
        {
            a = line[ChrCount];       
            ChrCount++;

            if (a == ",")
            {
                commacount++; 
            }

            else if (commacount == column) 
            {
                companyname.append(a);
            }

            else if (commacount > column) 
            {
                break;
            }

            if (companyname == input)
            {
                cout << endl << line;
            }
        }
    }
}

2 个答案:

答案 0 :(得分:6)

首先,应将逗号解析为空格。您可以通过更改流的区域设置中的内部std::ctype<charT>构面来执行此操作:

struct csv_classification : std::ctype<char> {
    csv_classification() : ctype(make_table()) { }
private:
    static mask* make_table() {
        const mask* classic = classic_table();
        static std::vector<mask> v(classic, classic + table_size);
        v[','] |= space;
        v[' '] &= ~space;
        return &v[0];
    }
};

然后使用以下方式设置区域设置:

ifs.imbue(std::locale(ifs.getloc(), new csv_classification));

接下来制作一个操纵器,检查你是否在行尾。如果是,则在流状态中设置std::ios_base::failbit标志。还可以使用内部存储来判断记录是否属于地图中的键或值。从Dietmar借了一点...

static int row_end = std::ios_base::xalloc();

std::istream& record(std::istream& is) {
    while (std::isspace(is.peek())) {
        int c(is.peek());
        is.ignore();

        if (c == '\n') {
            is.iword(row_end) = !is.iword(row_end);
            is.setstate(std::ios_base::failbit);
        }
    }
    return is;
}

然后你可以这样做:

std::vector<std::string> keys, values;

for (std::string item;;) {
    if (ifs >> record >> item)
        keys.push_back(item);
    else if (ifs.eof())
        break;
    else if (ifs.iword(row_end)) {
        ifs.clear();
        while (ifs >> record >> item)
            values.push_back(item);
    }
    else
        break;
}

现在我们需要应用键和值并打印出来。我们可以为此创建一个新算法:

template<class Iter1, class Iter2, class Function>
void for_each_binary_range(Iter1 first1, Iter1 last1,
                           Iter2 first2, Iter2 last2, Function f)
{
    assert(std::distance(first1, last1) <= std::distance(first2, last2));

    while (first1 != last1) {
        f(*first1++, *first2++);
    }
}

最后我们这样做:

for_each_binary_range(std::begin(keys),   std::end(keys),
                      std::begin(values), std::end(values),
[&] (std::string const& key, std::string const& value)
{
    std::cout << key << ": " << value << std::endl;
}

Live Demo

答案 1 :(得分:0)

这是您的解决方案(最接近您的要求):

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

using namespace std;

typedef std::vector<std::string> record;

std::istream&
operator>>(
  std::istream& is,
  record&       r)
{
  r.clear();

  string line;
  getline(is, line);

  istringstream iss(line);
  string field;

  while (getline(iss, field, ',' ))
    r.push_back(field);

  return is;
}

int
main()
{

  ifstream file("Stock Database.csv");
  record headers, r;

  if (file.good())
    file >> headers;

  while (file >> r)
  {
    for (int i = 0; i < r.size(); i++)
      cout << headers[i] <<  ":\t" << r[i] << endl;

    cout << "------------------------------" << endl;
  }

  return 0;
}

// EOF

&#34; Stock Database.csv&#34;的内容文件是:

Symbol,Name,Price,High Today,Low Today,52 Week Low
GOOG,Google Inc.,$568.77 ,$570.25 ,$560.35
AAPL,Apple Inc.,$93.28 ,$63.89 ,$99.44

只需记录你想要的任何内容。从文件中读取的第一个假设是为您带来标题。每次下一次读取都会用csv值填充每条记录。