CSV解析与c ++ [英] CSV Parsing with c++

查看:201
本文介绍了CSV解析与c ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个代码,将通过csv数据库解析股票信息。目前,我有生成的代码,以便它将搜索一个关键字并打印整行,但我试图得到它,以便它将打印整行与标题行以一个格式化的方式。

I'm trying to create a code that will parse through a csv database with stock information. Currently, I have the code generated so that it will search with a keyword and print the whole row, but I'm trying to get it so that it will print the whole row with the header row in a neatly formatted way.

我试图得到它,所以如果我搜索谷歌,它会返回

I'm trying to get it so that if I searched Google, it'd return


符号GOOG

NAME Google Inc

高今天$ 568.77

Symbol GOOG
NAME Google Inc
High Today $568.77

如何csv看起来像:


符号,名称,价格,高今天,低今天,52周低

GOOG,Google Inc。,$ 568.77,$ 570.25,$ 560.35

AAPL,Apple Inc.,$ 93.28,$ 63.89,$ 99.44。

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.

代码:

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;
            }
        }
    }
}


推荐答案

首先,一个逗号应该被解析为空格。您可以通过更改流的语言环境中的内部 std :: ctype< charT> 构面来执行此操作:

First a comma should be parsed as whitespace. You can do this by changing the internal std::ctype<charT> facet in the stream's locale:

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];
    }
};

然后使用以下方式设置语言环境:

Then set the locale using:

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

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

Next make a manipulator that checks to see if you're at the end of the line. If you are it sets the std::ios_base::failbit flag in the stream state. Also use internal storage to tell if the record belongs as a key or value in the map. Borrowing a bit from 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;
}



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

Now we need to apply both the keys and values and print them out. We can create a new algorithm for that:

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;
}

现场演示

这篇关于CSV解析与c ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆