簡體   English   中英

讀取CSV文件以檢測文件中的最后一個字段

[英]Reading a CSV file detecting last field in file

我正在嘗試讀取CSV文件,我應該讀取三個字段,最后一個字段是整數,並且由於沒有換行符,我使用stoi函數崩潰了文件的最后一行而且我不確定如何檢測我何時處於最后一行。 前兩個getline語句正在讀取前兩個字段,而我的第三條getline正在讀取並期望一個整數,而我的定界符僅是'\\ n',但這不適用於最后一行輸入,我想知道有什么解決方法嗎?

我期望的字段類型為[int,string,int],並且我必須在中間字段中包含空格,因此我認為使用stringstream不會有效

while (! movieReader.eof() ) { // while we haven't readched end of file
    stringstream ss;
    getline(movieReader, buffer, ','); // get movie id and convert it to integer
    ss << buffer; // converting id from string to integer
    ss >> movieid;
    getline(movieReader, movieName, ','); // get movie name
    getline(movieReader, buffer, '\n');
    pubYear = stoi(buffer); // buffer will be an integer, the publish year
    auto it = analyze.getMovies().emplace(movieid, Movie(movieid, movieName, pubYear ) );
    countMovies++;
}

為了讀取和寫入對象,流式提取和流插入運算符在概念上會過載:

范例csv:

1, The Godfather, 1972
2, The Shawshank Redemption, 1994
3, Schindler's List, 1993
4, Raging Bull, 1980
5, Citizen Kane, 1941

碼:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>

void skip_to(std::istream &is, char delim) // helper function to skip the rest of a line
{

    char ch;
    while ((ch = is.get()) && is && ch != delim);
}

std::istream& eat_whitespace(std::istream &is) // stream manipulator that eats up whitespace
{
    char ch;
    while ((ch = is.peek()) && is && std::isspace(static_cast<int>(ch)))
        is.get();
    return is;
}

class Movie
{
    int movieid;
    std::string movieName;
    int pubYear;

    friend std::istream& operator>>(std::istream &is, Movie &movie)
    {
        Movie temp;  // use a temporary to not mess up movie with a half-
        char ch;     // extracted dataset if we fail to extract some field.

        if (!(is >> temp.movieid))  // try to extract the movieid
            return is;

        if (!(is >> std::skipws >> ch) || ch != ',') { // read the next non white char
            is.setf(std::ios::failbit);                // and check its a comma
            return is;
        }

        is >> eat_whitespace; // skip all whitespace before the movieName
        if (!std::getline(is, temp.movieName, ',')) {  // read the movieName up to the
            return is;                                 // next comma
        }

        if (!(is >> temp.pubYear))                     // extract the pubYear
            return is;

        skip_to(is, '\n');  // skip the rest of the line (or till eof())
        is.clear();

        movie = temp;  // all went well, assign the temporary
        return is;
    }

    friend std::ostream& operator<<(std::ostream &os, Movie const &movie)
    {
        os << "Nr. " << movie.movieid << ": \"" << movie.movieName << "\" (" << movie.pubYear << ')';
        return os;
    }
};

int main()
{
    char const * movies_file_name{ "foo.txt" };
    std::ifstream is{ movies_file_name };

    if (!is.is_open()) {
        std::cerr << "Couldn't open \"" << movies_file_name << "\"!\n\n";
        return EXIT_FAILURE;
    }

    std::vector<Movie> movies{ std::istream_iterator<Movie>{is},
                               std::istream_iterator<Movie>{} };

    for (auto const & m : movies)
        std::cout << m << '\n';
}

輸出:

Nr. 1: "The Godfather" (1972)
Nr. 2: "The Shawshank Redemption" (1994)
Nr. 3: "Schindler's List" (1993)
Nr. 4: "Raging Bull" (1980)
Nr. 5: "Citizen Kane" (1941)

暫無
暫無

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

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