[英]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
讓我覺得這段代碼有一些不必要的開銷。 我嘗試了幾種方法,例如使用ifstream
的operator>>
,但這要么沒有產生真正的改進,要么開始破壞 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
防止了float
和double
之間的轉換錯誤(我們正在讀取並存儲為double
)並且%*c
指示識別字符但不存儲它,因此有效地跳過了逗號。 它看起來像代碼高爾夫,但它有效(或至少看起來有效)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.