[英]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.