c++ - 动态改变数组的大小并读入值。(无载体)
问题描述
您好,我遇到以下困难,我正在尝试读取双精度表(每行 1 个条目)并将其存储在数组中,同时动态更改该数组的大小(对于每行/条目)。这是一个学校作业,它禁止使用向量(会容易得多......)。我的主要想法是有一个存储值的主数组,然后将前一个值和下一个值存储到一个新数组中并迭代地执行此操作。目前,我遇到的问题是只存储表的最后一个值。我知道,不知何故,我需要通过引用全局函数来传递数据,并且我正在使用的指针在它们退出下面的 while 迭代后变为空。但是,由于数据的确切长度未知,这似乎是不可能的,因为在 main() 中初始化数组是不可能的(确切长度未知)。任何帮助,将不胜感激。代码贴在下面。
编辑:在考虑了这两条评论后,我对代码进行了以下更改,但是我不确定它们是否会表现得适当。我添加了一个名为 的新函数add_new_datapoint
,它应该全局更改指针/长度的值,这是通过引用传递值来完成的。在有问题的 else 语句中调用 add_new_datapoint(data_ptr, data_len, new_dp)。另外,我不确定将新内存重新分配给指针变量是否会导致内存泄漏。本质上(在我重新分配之后data_ptr
是“被指向”的内存被释放,还是我必须删除它然后在.中重新初始化它。在这种情况下,我可以在下一次迭代中再次引用指针“data_ptr”吗的循环?
解决方案
我认为简化发布的代码比试图找到所有可能出错的地方更容易。
如果您希望只看到double
文件中的值,则可以将用于从文件中读取数据的代码简化为:
while ( data_file >> new_data_pt )
{
// Use new_data_pt
}
如果您预计可能存在 double
s 以外的值,则可以使用:
while ( getline(data_file, line) )
{
std::istringstream str(line);
while ( str >> new_data_pt )
{
// Use new_data_pt
}
}
但是您必须了解代码在遇到错误后不会再从一行中读取任何值。如果您的行包含
10.2 K 25.4
代码将读取10.2
,遇到错误K
,并且不会处理25.4
。
要处理的代码new_data_pt
是它需要存储在一个动态分配的数组中。我建议把它放在一个函数中。
double* add_point(double* data_ptr, int data_len, double new_data_pt)
将该函数称为:
data_ptr = add_point(data_ptr, data_len, new_data_pt);
假设第一个while
循环,内容main
变为:
int main()
{
std::fstream data_file{ "millikan2.dat" };
// It is possible that the file has nothing in it.
// In that case, data_len needs to be zero.
int data_len{ 0 };
// There is no need to allocate memory when there is nothing in the file.
// Allocate memory only when data_len is greater than zero.
double* data_ptr = nullptr;
double new_data_pt;
if (!data_file.good()) {
std::cerr << "Cannot open file";
return 1;
}
while ( data_file >> new_data_pt )
{
++data_len;
data_ptr = add_point(data_ptr, data_len, new_data_pt);
}
// No need of this.
// The file will be closed when the function returns.
// data_file.close();
}
add_point
可以实现为:
double* add_point(double* data_ptr, int data_len, double new_data_pt)
{
double* new_data_ptr = new double[data_len];
// This works even when data_ptr is nullptr.
// When data_ptr is null_ptr, (data_len - 1) is zero. Hence,
// the call to std::copy becomes a noop.
std::copy(data_ptr, data_ptr + (data_len - 1); new_data_ptr);
// Deallocate old memory.
if ( data_ptr != nullptr )
{
delete [] data_ptr;
}
new_data_ptr[data_len-1] = new_data_pt;
return new_data_ptr;
}
跟踪坏点数量的代码要复杂得多。除非您必须这样做,否则我建议您忽略它。
推荐阅读
- javascript - 如何推动元素反应钩子状态数组
- floating-point - 浮点精度和运算顺序
- angular - 如何通过打字稿中的指令阻止垫选择?
- python - Selenium chromedriver python 允许多次下载
- c# - Xamarin.Forms. XAML Label IsVisible condition is not getting evaluated as expected
- r - dplyr::mutate() 的向量化函数
- hyperledger-fabric - Fabric python SDK中关于channel的一些问题
- matlab - 如何使用超越方程拟合绘图?
- javascript - 离线时空白页
- javascript - Bootstrap 手动折叠