Hey guys I'm having a lot of trouble getting this program to work. I want to keep an inventory of different tools using a random-access file that shows the name of the tool, how many of each tool I have on hand, and the cost. I then want to put all this info. into a .dat file and be able to list all the tools, delete a record for a tool, and update a tool's information.

When I compile the code I get no errors, but when I try to run it I get an error saying assertion failed string subscript our of range. Any help with this would be much appreciated.

Recommended Answers

All 14 Replies

Please use code tags to post the smallest compilable example of the problem. Subscript out of range means you are doing something like myArray[5] when the array only has 3 elements, or something like that.

Dave

hey thanks for replying, I didn't use code tags because I thought it would be too long, let me know if they are too long thanks!

.......too long sorry about that! Let me see if I can reduce it.

Yes yes, too long! haha - Try to abstract the problem to < 20 lines that we can look at.

Dave

Since the error seems to have something to do with string, I'm thinking it might have something to do with the way I'm naming my tools? The code below is used to insert data for a tool is this looking ok? Hopefully that isn't too much code.

void insertData()
{
	Hardware tool1;

	ofstream st("Hardware.dat", ios::in | ios::out | ios::binary );

	if(!st)
	{
		cout << "File not found.";
		exit(0);
	}

	int myRecordNumber;
	char tname[15];
	int myQuantity;
	double myCost;

	cout << "Enter tool number: " << endl;
	cin >> myRecordNumber;
	tool1.setRecordNumber(myRecordNumber);

	cout << "Enter tool name: " << endl;
	cin >> tname;
	tool1.setToolName(tname);

	cout << "Enter the quantity: " << endl;
	cin >> myQuantity;
	tool1.setQuantity(myQuantity);

	cout << "Enter the cost: " << endl;
	cin >> myCost;
	tool1.setCost(myCost);

	st.seekp((myRecordNumber)*sizeof(Hardware));

	st.write(reinterpret_cast<const char*>(&tool1),sizeof(Hardware));
}

I don't know if everyone here agrees, but I am much more inclined to help when the code is immediately compilable:

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

class Hardware
{
  int a;
};

int main()
{
    Hardware tool1;
	ofstream st("Hardware.dat", ios::in | ios::out | ios::binary );

	if(!st)
	{
		cout << "File not found.";
		exit(0);
	}

	int myRecordNumber;
	char tname[15];
	int myQuantity;
	double myCost;

	cout << "Enter tool number: " << endl;
	cin >> myRecordNumber;

	cout << "Enter tool name: " << endl;
	cin >> tname;

	cout << "Enter the quantity: " << endl;
	cin >> myQuantity;

	cout << "Enter the cost: " << endl;
	cin >> myCost;

	st.seekp((myRecordNumber)*sizeof(Hardware));

    st.write(reinterpret_cast<const char*>(&tool1),sizeof(Hardware));
    
    return 0;
}

First - I think you should typical exit(-1) to indicate an error, right? I think exit(0) ( like return 0) means "everything went ok" (but maybe I'm wrong about this?)

When I run this code, I get "File not found". Since you are using ofstream, this should be trying to write (create) the file, right? So it shouldn't matter if the file is already created?

Looking at the code some more I thought I'd add the set function for my tool name.

void Hardware::setToolName(string tn)
{
	for(int i=0; i < 15; i++)
		toolName[i]=tn[i];
}

This is used to limit the number of characters in a name.

Actually I have something before that, that creates the file. I tried switching the exit to (-1) but there was no change so I don't think it matters.

I'm really not sure how to shorten the code and still have it working, any ideas?

You're right, of course how you're exiting doesn't matter to your real problem. I was just pointing it out in parallel.

Another thing - I would highly recommend explicitly using the "this" pointer to indicate when you are addressing member variables:

void Hardware::setToolName(string tn)
{
	for(int i=0; i < 15; i++)
		this->toolName[i]=tn[i];
}

It will really improve code readability.

This is the demo I have for writing a binary file:

float fnum[4] = {11.22, -33.44, 55.66, 77.88};
	int i;

	ofstream out(Filename.c_str(), ios::out | ios::binary);
	if(!out)
	{
		cout << "Cannot open file.";
		exit (-1);
	}
	
	out.write((char *) &fnum, sizeof(fnum));
	out.close();

Maybe this will help you get a bit further?

Dave

Here is what I have for writing the file with 100 records.

void createData()
{
	Hardware tool1;
	ofstream st("Hardware.dat", ios::out | ios::binary);
	if(!st)
	{
		cout << "File not found.";
		exit(-1);
	}
	for(int i=0; i<100; i++){
		st.write(reinterpret_cast<const char*>(&tool1),sizeof(Hardware));
		}
	cout << "\nCreated 100 blank tools.";
}

That would just write the same tool 100 times, right?

Please clearly define what is going on - what is your expected output? What is the current output? Are there compiler errors?

That should just create 100 blank records, then using the code I posted before insertData() should insert the information of a tool into one of the blank records. There are no compile errors however when I try to run the program I still get that subscript out of range error message.

I'm trying to shorten my code but I still can't figure out how to shorten it and still have it all compile.

This compiles and runs fine for me:

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

class Hardware
{
  int a;
};

int main()
{

	Hardware tool1;
	ofstream st("Hardware.dat", ios::out | ios::binary);
	if(!st)
	{
		cout << "File not found.";
		exit(-1);
	}
	for(int i=0; i<100; i++){
		st.write(reinterpret_cast<const char*>(&tool1),sizeof(Hardware));
		}
	cout << "\nCreated 100 blank tools.";
    
    return 0;
}

If you can make something approximately this length that produces the out of range error that would be very helpful.

Ah I fixed the error and got it to compile. I just changed my tool name to string and it worked! However, some things are not working correctly, for one when I end the program and start it again it does not remember the tool I entered before. Could this be a problem with the writing of the file?

Okay I was able to figure it out! Thanks Dave for helping me out. :)

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.