开发者

opening and reading a file whose name is given at runtime

开发者 https://www.devze.com 2023-03-24 00:39 出处:网络
My problem is how to use correctly the function infile.open(). I have a class that, among the others, has the following public properties:

My problem is how to use correctly the function infile.open().

I have a class that, among the others, has the following public properties:

class myclass {
public:
int rows
int columns
const char* array_file
}

All values are given at run-time.

When I call the function that uses a member of the class I have (pt is a pointer to a member of the class)

#include <vector>
#include <fstream>
#include <iostream>
typedef std::vector< std::vector<int> > Matrixint;

void function(myclass* pt) { 
    Matrixint array_name(pt->rows, std::vector<int>(pt->columns));

    std::ifstream infi开发者_运维问答le;

    infile.open("%s", pt->array_file); // my problem: is this correct?
    for (int a = 0; a < pt->rows; a++) {
         for (int b = 0; b < pt->columns; b++) {
               infile >> array_name[a][b] ;
         }
    }
    infile.close();

}

Is this way of opening/reading the file correct?

The data in the file will be formatted as in this question (please note: only the array will be present in the file, no other data)


infile.open gets as its first parameter the filename:

void open ( const char * filename, ios_base::openmode mode = ios_base::in );

(source)

I don't know what your filename is but maybe something like this (just a guess based on variable types) could do:

infile.open(pt->array_file); 

of course you have to ensure that the filename you pass in is correct at the time of calling that function.


Assuming that my psychic abilities for fixing your question's code were right, I'd write it like this:

struct mine {
    int rows
    int columns
    std::string array_file
}

void function(const mine& m) { 
    Matrixint array_name(pt->rows, std::vector<int>(pt->columns));

    std::ifstream infile(m.array_file.c_str());

    for (int a = 0; a < ls->rows && infile.good(); ++a) {
         for (int b = 0; b < ls->columns && infile.good(); ++b) {
               infile >> array_name[a][b] ;
         }
    }

    if(!infile) 
        throw "Uh oh!"; // assume real error handling here
}

Why have I changed all these things?

  • A class with all public data isn't a class, but an aggregation of data. I'd use a struct for that, to not to confuse those who later need to maintain my code. (That might include me a few years down the road, which is a strong incentive to be very helpful.)
  • Unless you know exactly what you're doing (which doesn't seem to be the case), you should be using std::string rather than C-style strings.
  • Why pass the function parameter by pointer, when you can use a const reference?
  • std::ifstream has a constructor with which you can open a file immediately. I rarely ever use (or see used) its open() member function.
  • You need to test whether the file was opened and whether the input operations succeeded. (In this case, I merged the test whether it could be opened with the input operation succeed test, since the for loop is a pre-testing loop.) After the operations, I check whether an error occurred. Alternatively you could break out of the loop with an exception when reading fails.
  • Usually there is no need to close a stream, since its destructor already does this. If you make your variables as local as possible (which is good programming praxis), the file will be closed right away nevertheless.
0

精彩评论

暂无评论...
验证码 换一张
取 消