如何遍历csv文件,然后将每一列拆分为一个向量



所以我有一个CSV,有两列——一列用于歌曲,一列用于该歌曲的艺术家。例如

The Pretender,Foo Fighters
In Bloom,Nivana
Champagne Supernova,Oasis
Starlight,Muse
Will We Talk?,Sam Fender

我正在将我写了一段时间的python程序转换为c++。在该程序中,它使用csv库读取csv,并从中随机选择一行。然后它将其分为两列,然后将它们存储在变量中,答案是歌曲名称,标题是歌曲标题:

#select a random row and store it in a list
randomrow = random.choice(list(csvreader))
#print(randomrow)
answer = randomrow[0]
answer = answer.strip()
#print(answer)
track = randomrow[0]
#print(track)
#split track into two columns - title and artist
title = track.split()

我已经尝试了这个线程的技术:在这里

例如:

#include <sstream>
#include <string>
#include <fstream>
#include <iostream>
std::ifstream songsCsv("Songs.csv");
std::string line;
while (std::getline(songsCsv line))
{
std::istringstream iss(line);
std::string song, artist;
if (!(iss >> song >> artist)) { break; }
cout << song;
cout << artist;
}

然而,这里什么也没输出。如果有人对如何做这件事有任何想法,我们将不胜感激。

根据您的CSV文件,您可以有这样的解决方案:

#include <sstream>
#include <string>
#include <fstream>
#include <iostream>
#include <vector>
int main()
{
std::vector<std::pair<std::string, std::string>> result;
std::string line;
std::string first, second;
std::ifstream ifs("Songs.csv");
while (std::getline(ifs, line))
{
std::istringstream iss(line);
std::getline(iss, first, ',');
std::getline(iss, second, ',');
result.push_back(std::make_pair(first, second));
}
for (std::vector<std::pair<std::string, std::string>>::const_iterator it = result.cbegin(); it != result.cend(); ++it)
{
std::cout << it->first << " : " << it->second << 'n';
}
return 0;
}

如果你有两列以上(一首以上的歌曲(,一个更安全的解决方案是迭代从CSV文件中检索到的行,并将其附加到std::map<std::string, std::vector<std::string>>中,其中键是乐队的名称。

编辑

这里是使用std::map的另一个解决方案,其中第一个成员是乐队的名称。如果您有两列以上(一首以上的歌曲(,并且CSV文件的最后一列是乐队名称,则首选此列。

例如,您可以有以下CSV文件:

The Pretender,AAAA,Foo Fighters
In Bloom,BBBB,Nivana
Champagne Supernova,CCCC,Oasis
Starlight,DDDD,Muse
Will We Talk?,EEEE,FFFF,Sam Fender

问题是>>只在空白(换行符、制表符、空格(周围拆分单词。

受此问题启发,您可以将分隔符更改为逗号,如下所示:

#include <locale>
#include <iostream>

struct comma_is_space : std::ctype<char> {
comma_is_space() : std::ctype<char>(get_table()) {}
static mask const* get_table()
{
static mask rc[table_size];
rc[','] = std::ctype_base::space;  // split on commas
return &rc[0];
}
};
{
...
std::istringstream iss(line);
iss.imbue(std::locale(iss.getloc(), new comma_is_space()));
...
}

最新更新