我正在使用具有"main"
功能和其他一些功能的项目。
我想在主要功能中打开.data
文件,并在另一个功能(如"getsize"
中读取它,然后在"store_num"
中读取文件。
首先,似乎我必须传递一些指向函数的参数或指针,以便它们可以识别.data
文件。该怎么办?
第二,我希望文件中的内容只读取一次,而不是在每个不同的功能中再次读取.data
文件中的所有内容。我该怎么办?
我的代码中可能存在一些错误,但是我认为理解我的问题就可以了。
#include <iostream>
#include <fstream>
typedef struct value {
int x, y, value;
bool check;
}value;
typedef struct peak {
int col, row;
}peak;
class testcase {
public:
void getsize(value*);
void store_num(int, value*);
void peaktest(int);
int row = 1;
int peak_num = 0;
void set_peak(int, int);
value* array;
peak peak_list[10];
int row_num, col_num;
};
int main(int argc, char * argv[]) {
std::fstream myfile("matrix.data", std::ios_base::in);
testcase* map;
map->getsize(map->array);
map->store_num(1, map->array);
for (int countrow = 2; countrow <= map->row_num; countrow++) {
map->store_num(countrow,map->array);
map->peaktest(countrow - 1);
}
map->peaktest(map->row_num);
return 0;
}
void testcase::getsize(value* array) {
//std::cin >> row_num >> col_num;
myfile >> row_num >> col_num;
array = new value[row_num*col_num];
}
void testcase::store_num(int row, value* array) {
if (row == 1 || row == 2 || row == 3) {
for (int count = 0; count < col_num; count++) {
/*std::cin*/ myfile >> (array + (row - 1)*col_num + count)->value;
(array + (row - 1)*col_num + count)->check = true;
if (count > 0) {
if ((array + (row - 1)*col_num + count)->value >
(array + (row - 1)*col_num + count - 1)->value) {
(array + (row - 1)*col_num + count - 1)->check = false;
}
else if ((array + (row - 1)*col_num + count)->value <(array
+ (row - 1)*col_num + count - 1)->value){
(array + (row - 1)*col_num + count)->check = false;
}
}
if (row > 1) {
if ((array + (row - 1)*col_num + count)->value >
(array + (row - 2)*col_num + count)->value) {
(array + (row - 2)*col_num + count)->check = false;
}
else if ((array + (row - 1)*col_num + count)->value <(array + (row - 2)*col_num + count)->value) {
(array + (row - 1)*col_num + count)->check = false;
}
}
}
}
else {
for (int count = 0; count < col_num; count++) {
/*std::cin*/myfile >> (array + ((row - 1) % 3) + count)->value;
(array + ((row - 1) % 3) + count)->check = true;
if (count > 1) {
if ((array + ((row - 1) % 3) + count)->value > (array + ((row - 1) % 3) + count - 1)->value) {
(array + ((row - 1) % 3) + count - 1)->check = false;
}
else if ((array + ((row - 1) % 3) + count)->value < (array + ((row - 1) % 3) + count - 1)->value) {
(array + ((row - 1) % 3) + count)->check = false;
}
}
if ((array + ((row - 1) % 3) + count)->value > (array + ((row + 1) % 3) + count)->value)
(array + ((row + 1) % 3) + count)->check = false;
else if ((array + ((row - 1) % 3) + count)->value < (array + ((row + 1) % 3) + count)->value)
(array + ((row - 1) % 3) + count)->check = false;
}
}
}
void testcase::peaktest(int row) {
for (int col = 1; col <= col_num; col++) {
if ((array + (row - 1)*row_num + (col - 1))->check == true)
set_peak(row, col);
}
}
void testcase::set_peak(int row ,int col) {
peak_list[peak_num].row = row;
peak_list[peak_num].col = col;
peak_num++;
}
答案 0 :(得分:2)
通过引用将文件流传递给需要它的其他函数。
while()
关于危险信息,
class testcase {
public:
void getsize(value*, std::fstream & myfile);
void store_num(int, value*, std::fstream & myfile);
...
};
int main() {
std::fstream myfile("matrix.data", std::ios_base::in);
testcase* map; // Danger Will Robinson! Danger!
map->getsize(map->array, myfile);
map->store_num(1, map->array, myfile);
for (int countrow = 2; countrow <= map->row_num; countrow++) {
map->store_num(countrow,map->array, myfile);
map->peaktest(countrow - 1);
}
...
}
分配指向testcase* map;
的指针,但不指向任何内容。你可以
testcase
,但是这里不需要动态分配。考虑丢弃指针。
testcase* map = new testcase;
解决这个问题,我看到一个错误:
int main() {
std::fstream myfile("matrix.data", std::ios_base::in);
testcase map;
map.getsize(map.array, myfile);
map.store_num(1, map.array, myfile);
for (int countrow = 2; countrow <= map->row_num; countrow++) {
map.store_num(countrow,map.array, myfile);
map.peaktest(countrow - 1);
}
map.peaktest(map.row_num);
return 0;
}
传入指针时,指向的数据(如果有)通过引用传递。指针本身不是。 void testcase::getsize(value* array, std::fstream & myfile) {
myfile >> row_num >> col_num;
array = new value[row_num*col_num];
}
保留了用于调用array
的地址的副本,并且是一个受getsize
限制的自动变量。当getsize
超出范围时,在函数内部分配给array
的分配将丢失。这使传递的值保持不变。哎呀。通常情况下
array
并传递参考。但是...
我发现自己想知道为什么将对象自己的数据传递给其方法之一? void testcase::getsize(value*& array, std::fstream & myfile) {
myfile >> row_num >> col_num;
array = new value[row_num*col_num];
}
实例已经知道testcase
。我们可以直接分配给它。例如
array
接下来,如果在调用void testcase::getsize(std::fstream & myfile) {
myfile >> row_num >> col_num;
array = new value[row_num*col_num];
}
时testcase
实例已经有分配,该怎么办? getsize
泄漏了它。您要添加一个将array = new value[row_num*col_num];
设置为array
nullptr
然后
testcase::testcase(): array(nullptr)
{
}
其他可能性是使void testcase::getsize(std::fstream & myfile) {
delete[] array;
myfile >> row_num >> col_num;
array = new value[row_num*col_num];
}
重载以读入operator>>
。可以在What are the basic rules and idioms for operator overloading?中找到关于此的信息,然后testcase
和getsize
消失。它们内置在store_num
中,operator>>
的前几行变为
main
其中可能存在更多错误,但我不是在寻找它们。相反,我要咆哮。
testcase map;
myfile >> map;
是一种C主义。 C ++充分利用了20年左右的C语言,并消除了对typedef struct value {
int x, y, value;
bool check;
}value;
进行类型定义的麻烦,从而避免始终都键入struct
。 C ++非常清楚struct
是value
,所以除了爱,您需要的就是
struct
答案 1 :(得分:0)
将std::fstream myfile
放在类本身中,并在类的构造函数中使用文件名调用myfile.open
,或制作类似init
的方法并从那里调用myfile.open
。
如果您希望将myfile
变量保留在main
中,则将其传递给testcase
的构造函数,并使用类型为{的 reference 变量{1}}。这样:
std::fstream
答案 2 :(得分:0)
我的建议是添加一个类,该类的唯一职责是处理有关文件中的I / O。在调用其他函数之前,先在main中实例化它,然后将其作为参数传递并从中调用公共.get()方法获取下一行数据。如果仅将文件I / O放入测试用例类中,并且具有多个测试用例,则每个对象需要一个数据文件,否则每个对象都可能试图打开同一数据文件。这也可能会在文件中重新定位流游标,并给您带来意想不到的结果。最好让一个对象满足单一责任原则。
/*---------------------------------
* FileMgr class
----------------------------------*/
class fileMgr
{
private:
bool open;
std::string filename;
std::string buffer;
std::fstream myfile;
public:
//-- constructor with filename parameter
fileMgr(std::string filename)
: filename(filename)
{
buffer = "";
myfile = std::fstream(filename, std::ios_base::in | std::ios_base::app);
if(!myfile)
{
/*-----------------------------------
* check to make sure the file opened without
* any problems, and set a bit flag to tell
* which state it is in
-----------------------------------*/
std::cerr << "\nERROR: file manager cannot open file: " << filename << std::endl;
open = false;
}
else
{
/*---------------------------------------
* Otherwise it opened fine and we place the
* cursor at the beginning of the file
-----------------------------------------*/
open = true;
myfile.clear();
myfile.seekg(0, std::ios::beg);
}
}
//-- function to serve a result row
value get()
{
value newValue;
if(open)
{
std::getline(myfile, buffer);
//--- parse buffer for your data
}
return value;
}
};