CSV解析与c ++ [英] CSV Parsing with 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屋!