我尝试了其他答案中提到的一些修复,但它们对我的输出没有影响。我不打算使用提升精神,因为我不确定它是否是我需要的最佳选择。此类帖子也不涉及包含逗号的引用材料,这是我此时要解决的最后一个问题。
这是一个C ++程序。我使用CSV文件作为输入。此文件提供了封条的功能,每个条目有23个值(列)。当我输出rawdata [22]时,我希望看到第一组数据的最后一个条目。相反,我看到最后一个条目(请愿),然后是下一个印章的第一个条目(2055)。当我在十六进制编辑器中打开它时,我看到两个单词之间用“。”分隔。并且十六进制字符是0a。我试过设置\ r,\ n,\ r \ n作为分隔符,但它们不起作用。我不能使用“,”作为分隔符,因为它在字符串中使用,我测试它以查看它是否适用于我的问题而且它没有。如何分离这些值?
输出:
Petitioned
2055
示例输入:
SpeciesID,Kingdom,Phylum,Class,Order,Family,Genus,Species,Authority,Infraspecific rank,Infraspecific name,Infraspecific authority,Stock/subpopulation,Synonyms,Common names (Eng),Common names (Fre),Common names (Spa),Red List status,Red List criteria,Red List criteria version,Year assessed,Population trend,Petitioned 2055,ANIMALIA,CHORDATA,MAMMALIA,CARNIVORA,OTARIIDAE,Arctocephalus,australis,"(Zimmermann, 1783)",,,,,Arctophoca australis,South American Fur Seal,Otarie fourrure Australe,Oso Marino Austral,LC,,3.1,2016,increasing,N 41664,ANIMALIA,CHORDATA,MAMMALIA,CARNIVORA,OTARIIDAE,Arctocephalus,forsteri,"(Lesson, 1828)",,,,,Arctocephalus australis subspecies forsteri|Arctophoca australis subspecies forsteri,"New Zealand Fur Seal, Antipodean Fur Seal, Australasian Fur Seal, Black Fur Seal, Long-nosed Fur Seal, South Australian Fur Seal",,,LC,,3.1,2015,increasing,N
我的代码:
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int main() {
string line;
vector<string> rawdata;
ifstream file ( "/Users/darla/Desktop/Programs/seals.csv" );
if ( file.good() )
{
while(getline(file, line, '"')) {
stringstream ss(line);
while (getline(ss, line, ',')) {
rawdata.push_back(line);
}
if (getline(file, line, '"')) {
rawdata.push_back(line);
}
}
}
cout << rawdata[22] << endl;
return 0;
答案 0 :(得分:2)
这远不是一个完整的CSV解析器,可以提高效率,但它可以完成工作,正确解析文件并处理双引号。
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
int main()
{
std::string line;
std::vector<std::vector<std::string>> lines;
std::ifstream file("/Users/darla/Desktop/Programs/seals.csv");
if (file)
{
while (std::getline(file, line))
{
size_t n = lines.size();
lines.resize(n + 1);
std::istringstream ss(line);
std::string field, push_field("");
bool no_quotes = true;
while (std::getline(ss, field, ','))
{
if (static_cast<size_t>(std::count(field.begin(), field.end(), '"')) % 2 != 0)
{
no_quotes = !no_quotes;
}
push_field += field + (no_quotes ? "" : ",");
if (no_quotes)
{
lines[n].push_back(push_field);
push_field.clear();
}
}
}
}
for (auto line : lines)
{
for (auto field : line)
{
std::cout << "| " << field << " |";
}
std::cout << std::endl << std::endl;
}
return 0;
}
解释。程序读取文件行并尝试按字段解析每一行,用逗号分隔,然后将结果存储在向量的向量中。如果遇到双引号和双引号的字段为奇数,则表示它是一个开放字段,因此在读取关闭字段之前读入更多字段,然后存储完整字段。如果字段包含偶数个双引号或无引号,则会立即存储。希望这会有所帮助。