I wrote a program that opens a file using the command line (cmd), calculates a bunch of numbers, then outputs the results to another file.
The program works fine, but when I tried to alter my code using classes, all of a sudden the program is not fine.

Here is a basic outline of my program

void Bank::checkValid()
{

//code here
	

}
void Bank::outputToFile()
{
	//code here
}
int main (int argc, char* argv[]) 
{



	char* inputFileName= new char;

	inputFileName= strstr (argv[1],"=")+ 1;
	ifstream input;
	input.open (inputFileName, ifstream::in);
	
	Bank test;

  test.checkValid();
  test.outputToFile(); //will output results to another .txt file

	 
	  return 0;
}

I am thinking the file is not opening correctly as my program is unable to read the first char in my input file.

Does my code look ok?

I wanted to write a method inside my class that will open the file, but I don't know how to do that since I am only allowed to open the file using the cmd. I am thinking there is something wrong with the main body, can someone offer me some advice?

Recommended Answers

All 5 Replies

delete line 17 because the memory allocation is not necessary. strstr() returns the pointer that you want to use.

You are providing the filename via the command-line. You can open the file wherever you like, e.g. by passing the filename to a method.

As far as why it doesn't work, you say you can't read in the first character of the file, but there's nothing in the edited-down source you've posted to indicate where you're trying to do that. Let's start at the beginning, and see your declaration for you Bank class. Did you remember to include a default constructor method Bank() and a destructor method ~Bank()?

You are providing the filename via the command-line. You can open the file wherever you like, e.g. by passing the filename to a method.

As far as why it doesn't work, you say you can't read in the first character of the file, but there's nothing in the edited-down source you've posted to indicate where you're trying to do that. Let's start at the beginning, and see your declaration for you Bank class. Did you remember to include a default constructor method Bank() and a destructor method ~Bank()?

Hi rapter, so does that mean I should have a method in my class to open the file? I tried doing that but was unsuccessful, so I just open the file in my main body. Here is my declaration of my bank as well as my constructor and destructor.

#include <string>
#include <iostream>
#include <fstream>
using namespace std;
class Bank
{
private:
	ifstream input;
	bool badInput;
	char nextChar;
	int currentNumber;
	int sum;
	char firstChar;
	char lastChar;
	char* inputFileName;
public:
	Bank();
	~Bank();
	void checkValid();
	void outputToFile();
    
};
Bank::Bank()
{
	bool badInput=false;
	char nextChar='\0';
	int currentNumber=0;
	int sum=0;
	char firstChar='\0';
	char lastChar='\0';
	

}
Bank::~Bank()
{
}

So if I want to make a method to open my file, do I still need to have

int main (int argc, char* argv[])

in the main body? Or do I put that into a method like

int Bank::openFile(int argc, char* argv[])

I tried doing it, but I got an error saying it did not recognize argc and argv.

In no particular order:

Do not re-declare your member variables inside your constructor (lines 25-30). By specifying the types again, you have instead created local variables which mask your instance-members, and your instance-members are still uninitialized.

With that fixed, your constructor will be correct, but a preferred format is to initialize the members in an initialization-list, as follows:

Bank::Bank():
    badInput(false), nextChar('\0'), currentNumber(0), sum(0),
    firstChar('\0'), lastChar('\0')
{
    // any additional logic, besides initializing members, can go here
    // otherwise, leave it empty: {}
}

You still need int main (int argc, char *argv[]) , that's the only way for command-line arguments to get into your program.

If you have a whole bunch of different command-line arguments, especially optional ones, the code can get big enough that you might want a separate bool handleArgs(int argc, char *argv, Args & a) function which populated the members of an Args struct (note that in C++ a struct is just a class where everything is public by default) as appropriate, and returns true if the arguments were all valid and all required arguments were present, or false otherwise. But for now, handling the command-line in main() is fine.

You were fine up through

char* inputFileName= new char;
 
inputFileName= strstr (argv[1],"=")+ 1;

(though as AncientDragon pointed out, the first line leaks a tiny amount of memory, instead consolidate to char *inputFileName = strstr(argv[1], "=") + 1; )

But then, call a method passing the filename:

if (!bank.ReadFile(inputFileName)) {
    cout << "could not read file: " << inputFileName;
    return 1;
}

Also, in lines 8-15, the members of the class should only be those things that an instance of a Bank class needs to know about. Since a Bank instance probably doesn't care what file it was loaded from, char *inputFileName doesn't need to be a member. Same goes for ifstream input if you read the entire stream in one method -- it can just be a local variable in that method. Of course, if you want to read a line out of the file at a time, in various methods, then yes you could consider keeping the ifstream as a member.

Thank you very much!!! I appreciate all the help you have given me.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.