我正在尝试创建一个代码,该代码将使用库存信息解析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;
}
}
}
}
答案 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;
}
答案 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值填充每条记录。