簡體   English   中英

及時從 std::ifstream 讀取 CSV

[英]Reading CSV from std::ifstream in good time

我正在嘗試從std::ifstream讀取 x、y、z 值。 以下是它目前工作方式的大致輪廓:

struct Vec3 {

    Vec3(const double x, const double y, const double z) :
        x(x), y(y), z(z)
    {}

    double x, y, z;
}

std::vector<Vec3> readFile(std::ifstream& is) {
    std::vector<Vec3> retval;
    std::string str;
    while (std::getline(is, str)) {
        std::vector<std::string> strings;
        std::stringstream ss(str);
        for (std::string entry; std::getline(ss, entry, ','); ) {
            strings.push_back(entry);
        }
        const auto x = std::stof(strings[0]);
        const auto y = std::stof(strings[1]);
        const auto z = std::stof(strings[2]);
        retval.emplace_back(x, y, z);
    }
    return retval;
}

這工作得相當好,但是所涉及的string數量(以及使用sprintf_s以達到出色效果的相應文件寫入 function 的相對簡單性)讓我想知道是否有更快的方法來讀取ifstream並構造std::vector<Vec3> . 此外,使用std::getline兩次,以及每次都構造一個std::stringstream讓我覺得這段代碼有一些不必要的開銷。 我嘗試了幾種方法,例如使用ifstreamoperator>> ,但這要么沒有產生真正的改進,要么開始破壞 output。

我們可以做出的保證是每行的格式是帶有逗號分隔符的三個數字。

這對你有用嗎:

double x, y, z;
char c; // comma
while (is >> x >> c >> y >> c >> z) {
  retval.emplace_back(x, y, z);
}

我設法找到了一個比問題中發布的原始實現更好的組合,這在很大程度上受到了@0x499602D2 的回答的啟發。

std::vector<Vec3> readFile(std::ifstream& is) {
    double x, y, z;
    std::vector<Vec3> retval;
    std::string str;
    while (std::getline(is, str)) {
        sscanf_s(str.c_str(), "%lg%*c%lg%*c%lg", &x, &y, &z);
        retval.emplace_back(x, y, z);
    }
    return retval;
}

消除while循環非常有幫助。 至於奇怪的 sscanf 格式, %lg防止了floatdouble之間的轉換錯誤(我們正在讀取並存儲為double )並且%*c指示識別字符但不存儲它,因此有效地跳過了逗號。 它看起來像代碼高爾夫,但它有效(或至少看起來有效)。

暫無
暫無

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

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