簡體   English   中英

如何遍歷 csv 文件,然后將每一列拆分為一個向量

[英]How to iterate through a csv file and then split each column into a vector

所以我有一個 CSV 有 2 列 - 一個用於 A 歌曲,一個用於該歌曲的藝術家。 例如

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()

我已經嘗試過這個線程的技術: here

如:

#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;
}

如果您有超過 2 列(多於一首歌曲),則更安全的解決方案是遍歷從 CSV 文件和 append 檢索到的行到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 <sstream>
#include <string>
#include <fstream>
#include <iostream>
#include <map>
#include <vector>

int main()
{
    std::map<std::string, std::vector<std::string>> result;
    std::string line;
    std::ifstream ifs("Songs.csv");
    int i = 0;

    while (std::getline(ifs, line))
    {
        std::istringstream iss(line);
        std::vector<std::string> temp;
        for (std::string token; std::getline(iss, token, ','); )
        {
            temp.push_back(token);
        }

        result[temp[temp.size() - 1]].insert(result[temp[temp.size() - 1]].end(), std::make_move_iterator(temp.begin()), std::make_move_iterator(temp.end() - 1));
    }

    for (std::map<std::string, std::vector<std::string>>::const_iterator it = result.cbegin(); it != result.cend(); ++it)
    {
        std::cout << it->first << " : ";

        for (std::vector<std::string>::const_iterator vit = it->second.cbegin(); vit != it->second.cend(); ++vit)
        {
            std::cout << *vit << ' ';
        }

        std::cout << '\n';
    }
}

問題是>>只在空格(換行符、制表符、空格)周圍分割單詞。

受此問題的啟發,您可以將分隔符更改為逗號,如下所示:

#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()));
    ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM