CSV用c ++解析

use*_*859 1 c++ csv parsing

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

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

Symbol GOOG
NAME Google Inc
今日高位$ 568.77

csv如何看起来像:

符号,名称,价格,今日高点,今日低点,52周低点
Google,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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

0x4*_*2D2 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];
    }
};
Run Code Online (Sandbox Code Playgroud)

然后使用以下命令设置区域设置

ifs.imbue(std::locale(ifs.getloc(), new csv_classification));
Run Code Online (Sandbox Code Playgroud)

接下来制作一个操纵器,检查你是否在行尾.如果是,它将设置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;
}
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

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;
}
Run Code Online (Sandbox Code Playgroud)

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

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++);
    }
}
Run Code Online (Sandbox Code Playgroud)

最后我们做:

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;
}
Run Code Online (Sandbox Code Playgroud)

Live Demo