所以我有一个包含3个不同速度分量的文本文件,以及与每个速度测量相关的时间戳。 text file can be seen here。
u分量对应于x方向,v对应于y方向,w对应于z方向。现在,我需要获取这些数据点并将它们放入我的速度组件结构中,其定义为:
struct cmpnts
{
double x, y, z;
}
过去当我没有结构并且只有一个整体速度时,我只使用了指针,因此可以在读取文件时创建动态数组。这必须是动态的,因为每个windspeed文件中的点数都会发生变化,每次使用新文件时我都无法手动重新定义该值。
要在没有结构的情况下执行此操作,我的代码如下所示:
int main()
{
int numberofpoints; // the number of data points
// char arrays for storing the variables names
char ch1[128], ch2[128];
cout << ch1 << endl;
// Two pointers for creating the dynamic arrays later
double *itime, *windspeed;
// create an object for reading a file
ifstream imyfile;
// open windspeed.txt
imyfile.open("windspeed.txt");
if (imyfile.is_open()) // check if the file is open
{
// read the total number of data points
imyfile >> numberofpoints;
// double arrays for storing time and the velocity variables
itime = new double[numberofpoints];
windspeed = new double[numberofpoints];
// read the two variable names in windspeed.txt file
imyfile >> ch1 >> ch2;
// read the time and wind speed
int i;
for (i = 0; i<numberofpoints; i++)
{
imyfile >> itime[i] >> windspeed[i];
}
// close the file
imyfile.close();
}
else
{
cout << "unable to open the file";
exit(0);
}
}
我似乎无法让这个与我的结构一起工作。我确定我在指针的某处出现了一些语法错误(我是C ++的新手,所以如果它是愚蠢的话,我道歉!)。没有指针可以做到这一点吗?我阅读结构的代码看起来像这样(显然它不起作用!):
#include <iostream>
#include <fstream>
using namespace std;
struct cmpnts
{
double x, y, z;
};
struct wind
{
cmpnts velocity;
cmpnts direction;
cmpnts urms;
double airdensity;
};
struct turbine
{
double R, Cp, V, yaw, power;
cmpnts direction;
};
int main()
{
// Read data from file
int numberofpoints; // the number of data points
char ch1[128], ch2[128], ch3[128], ch4[128]; // Char arrays for storing the variables names
// Pointers for creating the dynamic arrays later
double *itime;
cmpnts *uSpeed;
cmpnts *vSpeed;
cmpnts *wSpeed;
// create an object for reading a file
ifstream imyfile;
// open windspeed.txt
imyfile.open("windspeed.txt");
if (imyfile.is_open()) // check if the file is open
{
// read the total number of data points
imyfile >> numberofpoints;
// double arrays for storing time and the velocity variables
itime = new double[numberofpoints];
uSpeed->x = new double[numberofpoints];
vSpeed->y = new double[numberofpoints];
wSpeed->z = new double[numberofpoints];
// read the two variable names in windspeed.txt file
imyfile >> ch1 >> ch2 >> ch3 >> ch4;
// read the time and wind speed
int i;
for (i = 0; i<numberofpoints; i++)
{
imyfile >> itime[i] >> uSpeed[i] >> vSpeed[i] >> wSpeed[i];
}
// close the file
imyfile.close();
}
else
{
cout << "unable to open the file";
exit(0);
}
}
答案 0 :(得分:1)
您的代码执行以下操作:
cmpnts *uSpeed;
这会创建一个变量uSpeed,可以在内存中保存cmpnts
实例的地址。指针没有真正的魔力,它们只是一个包含数值的变量。该值是某个东西的位置,它的地址,在内存中。我们将它标记为指针,以此作为尝试避免混淆变量的方法,这些变量是值和值为地址的变量。
这里的关键是这个指针是未初始化的。它可以包含零,也可以包含任何随机垃圾。
稍后,你写了
uSpeed->x = new double[numberofpoints];
->
是dereference
运算符。左边的变量必须是指向某种类型的东西的指针,然后右边的东西被假定为该地址处的东西的成员。
召回:您没有初始化uSpeed
。
但这里存在第二个问题。 cmpnts::x
是双倍的,但您正在尝试为其分配地址。
uSpeed->x = new double[numberofpoints];
vSpeed->y = new double[numberofpoints];
wSpeed->z = new double[numberofpoints];
你真的不清楚你认为你在这里做什么,但看起来你只是想要:
cmpnts* speed = new cmpnts[numberOfPoints];
然后
imyfile >> itime[i] >> speed[i].x >> speed[i].y >> speed[i].z;
使用指针很难。不要这样做。使用现代C ++。
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
struct Vector // note upper case for my own class
{
double x_, y_, z_; // the '_' distinguishes a member from a variable
};
struct SpeedEntry
{
int time_;
Vector vel_;
};
int main()
{
// create an object for reading a file
std::ifstream imyfile("windspeed.txt");
if (!imyfile.is_open()) // check if the file is open
{
std::cerr << "unable to open the file";
return 1; // non-zero return from main = failure
}
// read the total number of data points
size_t numberOfPoints;
imyfile >> numberofpoints;
imyfile.ignore(); // ignore end of line/whitespace
// for storing time and the velocity variables
std::vector<SpeedEntry> speeds;
speeds.reserve(numberOfPoints);
// read the two variable names in windspeed.txt file
// we're ignoring these values so...
std::string vars[4];
imyfile >> vars[0] >> vars[1] >> vars[2] >> vars[3];
std::cout << "vars are " << vars[0] << ", " << vars[1] << ", " << vars[2] << ", " << vars[3] << "\n";
// Now read each of the lines
for (size_t i = 0; i < numberOfPoints; ++i)
{
SpeedEntry entry;
if (!(imyfile >> entry.time_ >> entry.vel_.x_ >> entry.vel_.y_ >> entry.vel_.z_)) {
std::cerr << "Error reading entry #" << (i+1) << "\n";
return 2;
}
speeds.push_back(entry);
}
std::cout << "Read " << speeds.size() << " entries\n";
// c++11 range-based loop
for (auto&& entry : speeds)
{
std::cout << "Read: " << entry.time_ << " : "
<< entry.vel_.x_ << ',' << entry.vel_.y << ',' << entry.vel.z_
<< '\n';
}
} // file closes automatically when `imyfile` goes out of scope
进一步阅读:std::vector,std::string,
或利用operator<<
和operator>>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
struct Vector // note upper case for my own class
{
double x_, y_, z_; // the '_' distinguishes a member from a variable
};
// implement input and output operators for Vec
std::istream& operator >> (std::istream& in, Vector& vec)
{
return in >> vec.x_ >> vec.y_ >> vec.z_;
}
std::ostream& operator << (std::ostream& out, const Vector& vec)
{
return out << vec.x_ << ' ' << vec.y_ << ' ' << vec.z;
}
struct SpeedEntry
{
int time_;
Vector vel_;
};
// implement input and output operators for SpeedEntry
std::istream& operator >> (std::istream& in, SpeedEntry& entry)
{
return in >> entry.time_ >> entry.vel_;
}
std::ostream& operator << (std::ostream& out, const Vector& vec)
{
return out << entry.time_ << ' ' << entry.vel_;
}
int main()
{
std::ifstream imyfile("windspeed.txt");
if (!imyfile.is_open()) // check if the file is open
{
std::cerr << "unable to open the file";
return 1; // non-zero return from main = failure
}
// read the total number of data points
size_t numberOfPoints;
imyfile >> numberofpoints;
imyfile.ignore(); // ignore end of line/whitespace
// read the two variable names in windspeed.txt file
// we're ignoring these values so...
std::string vars[4];
imyfile >> vars[0] >> vars[1] >> vars[2] >> vars[3];
std::cout << "vars are " << vars[0] << ", " << vars[1] << ", " << vars[2] << ", " << vars[3] << "\n";
// for storing time and the velocity variables
std::vector<SpeedEntry> speeds;
speeds.reserve(numberOfPoints);
// Now read each of the lines
for (size_t i = 0; i < numberOfPoints; ++i)
{
SpeedEntry entry;
if (!(imyfile >> entry)) {
std::cerr << "Error reading entry #" << (i+1) << "\n";
return 2;
}
speeds.push_back(entry);
}
std::cout << "Read " << speeds.size() << " entries\n";
// c++11 range-based loop
for (auto&& entry : speeds)
std::cout << "Read: " << entry << '\n';
} // imyfile closes automatically when it goes out of scope
---编辑---
std::vector
几乎可以包含任何类型,因此您甚至可以构建复合向量:
std::vector<std::vector<std::string>> stringvecs;
这会创建类似于二维字符串数组的东西:
std::vector<std::vector<std::string>> stringvecs;
// allocates 5 empty std::vector<strings> in stringvecs
stringvecs.resize(5);
// push "hello world" onto the first entry
stringvecs[0].push_back("hello");
此时,stringvecs看起来像这样:
stringvecs {
[0] : std::vector of std::string containing { "hello" },
[1] : empty std::vector of std::string
[2] : "" "" "" ""
[3] : "" "" "" ""
[4] : "" "" "" ""
}
我们可以访问&#34;你好&#34;写作:
std::cout << stringvecs[0][0] << "\n";
记住:
stringvecs is of type std::vector<std::vector<std::string>>
if stringvecs.empty() == false
stringvecs[0] is of type std::vector<std::string> (returned by reference)
if stringvecs.empty() == false && stringvecs[0].empty() == false
stringvecs[0][0] is of type std::string (returned by reference)
当您使用结构的矢量时:
struct T {
int i_;
bool b_;
std::string s_;
};
std::vector<T> ts;
您首先需要访问向量中的T的实例才能访问其成员:
ts.emplace_back(1, false, "first"); // creates a T with these values
ts.emplace_back(2, true, "seconds");
std::cout << ts[0].s_ << "\n"; // access member "s_" of the first entry
std::cout << ts[1].i_ << "\n"; // prints 2, array indexes are 0-based
我挖了一个我曾在某人用过的矢量沙箱:http://ideone.com/HERvy1
浏览代码并将其与输出进行匹配。您还可以在此处找到有关std :: vector的更多信息:http://en.cppreference.com/w/cpp/container/vector