c++ - 使用 OOP 有效地处理和读取轨迹文件
问题描述
我正在编写一个代码来读取大型 .xyz 文件。这些类型的文件对于像 VMD 这样的分子动力学可视化工具很有用。所以文件格式看起来像这样
#Number of particles
#frame number
#Coordinates
举个例子:
5
0
C 1.23 2.33 4.56
C 1.23 2.33 5.56
C 1.23 2.33 6.56
C 1.23 2.33 7.56
C 1.23 2.33 8.56
5
1
C 2.23 2.33 4.56
C 2.23 3.33 5.56
C 2.23 4.33 6.56
C 2.23 5.33 7.56
C 2.23 6.33 8.56
等等。我试图在这里理解这篇文章https://codereview.stackexchange.com/questions/201743/processing-xyz-data-from-a-large-file讨论使用运算符重载方法从大型数据集中有效读取。我正在尝试编写一个可以读取如此大的轨迹文件并给我以下输出的类:1)粒子数 2)帧总数 3)每个时间步的坐标集。因此,我尝试根据这篇文章写下以下内容,以读取上述文件格式。到目前为止,下面的代码能够读取单个帧并在此之后退出。
#include <iostream>
#include <vector>
#include <fstream>
struct Particle{
long double x,y,z;
char tab ='\t';
char newline = '\n';
char atom ;
friend std::istream& operator>>(std::istream& in, Particle &xyz) {
in >> xyz.atom >> xyz.x >> xyz.y >> xyz.z ;
return in;
}
friend std::ostream& operator<<(std::ostream& out, Particle &xyz){
out << xyz.x << xyz.tab << xyz.y << xyz.tab << xyz.z << xyz.newline;
return out;
}
};
class XYZ_frame_read
{
int curr_frame;
int num_particles;
std::vector<Particle> coordinates_t;
public:
friend std::istream& operator>>(std::istream& in, XYZ_frame_read &traj ){
in >> traj.num_particles;
in >> traj.curr_frame;
Particle p;
while(in >> p){
traj.coordinates_t.push_back(p);
}
return in;
}
friend std::ostream& operator<<(std::ostream& out, XYZ_frame_read &traj){
for(int i = 0; i< traj.num_particles ;i ++){
out << traj.coordinates_t.at(i) ;
}
return out;
}
};
int main(int argc, char *argv[]){
std::ifstream in(argv[1]);
XYZ_frame_read* frames = new XYZ_frame_read[3];
in >> frames[0];
std::cout << frames[0];
return 0;
}
问题是我不明白我将如何实现此方法来读取下一帧并继续将它们附加到coordinates_t
每个 object 实例的向量中XYZ_frame_read
。我想我明白这是如何工作的,显然 awhile(!in.eof())
是毫无疑问的,因为它只会一遍又一遍地读取第一帧。我是 C++ 的新手,正在从事与分子动力学相关的项目,欢迎提出任何更改/建议!感谢您的帮助!
编辑
我试过使用
size_t i = 0;
while(in >> frames[i]){
std::cout << frames[i];
if(i == 3){
break;
}
i++;
}
它返回空白。它不起作用。循环甚至没有被执行。
解决方案
while(!in.eof())
是不可能的,因为eof
不像那样工作。
为什么循环条件内的 iostream::eof(即 `while (!stream.eof())`)被认为是错误的?
我不确定我看到了问题,有什么问题
size_t i = 0;
while (in >> frames[i])
++i;
(除了数组边界错误的可能性)。
编辑
此代码不正确
friend std::istream& operator>>(std::istream& in, XYZ_frame_read &traj) {
in >> traj.num_particles;
in >> traj.curr_frame;
Particle p;
while(in >> p){
traj.coordinates_t.push_back(p);
}
return in;
}
这表示继续读取粒子,直到读取失败。这是不正确的,你知道有多少粒子。它应该说继续阅读粒子,直到您阅读num_particles
它们(或阅读失败)。即应该说
friend std::istream& operator>>(std::istream& in, XYZ_frame_read &traj) {
in >> traj.num_particles;
in >> traj.curr_frame;
Particle p;
for (int i = 0; i < traj.num_particles && in >> p; ++i)
traj.coordinates_t.push_back(p);
}
return in;
}
推荐阅读
- html - 标志未满,背景图片
- javascript - 防止 401 XHR 错误出现在客户端控制台中
- asp.net - 如何在 Web 应用程序的页面上引用被覆盖的服务器控件
- json - 如何将数据从节点 js 存储到 JSON 文件?
- sql-server - 在 SQL Server 中展开表的日期
- javascript - 错误:未知提供者:AuditServiceProvider <- AuditService
- c# - C#反射,调用不同参数类型的方法
- mysql - Percona 查询指纹 - 为什么选择列中的顺序很重要?
- python - bokeh.charts 不见了——什么库可以做交互式彩色散点图?
- r - formatC() 在 R 中的 round(x) 产生后认为 0 为负数?