Hi folks,

I have googled around, read a lot and still can't figure it out. I know a bit of C++, but am far from literate in all commands. I am much happier with QBasic (old i know, but it works).

I have made qb code and need to convert it to C++ to teach myself the basics of random files access so i can actually use the knowledge in the program i have to make for my coursework. I have started on the C++ code, but am now stuck!

QB code : (If you got Vista/7/os-x or linux and want to run this code, you can get QB64 here : http://WWW.QB64.NET/)

TYPE SalesRecord
  Item1 AS INTEGER
  Item2 AS INTEGER
  Item3 AS INTEGER
  Item4 AS INTEGER
  Item5 AS INTEGER
END TYPE


REDIM TempRec(100) AS SalesRecord

OPEN "SalesRecord.txt" FOR RANDOM AS #1 LEN = LEN(TempRec())

FOR i% = 0 TO 99
  TempRec(i%).Item1 = INT(RND * 5)
  TempRec(i%).Item2 = INT(RND * 5)
  TempRec(i%).Item3 = INT(RND * 5)
  TempRec(i%).Item4 = INT(RND * 5)
  TempRec(i%).Item5 = INT(RND * 5)
  PUT #1, i% + 1, TempRec(i%)
NEXT

CLOSE #1


REDIM TempRec(100) AS SalesRecord

OPEN "SalesRecord.txt" FOR RANDOM AS #1 LEN = LEN(TempRec())

FOR i% = 0 TO 99
  GET #1, i% + 1, TempRec(i%)
  PRINT TempRec(i%).Item1; TempRec(i%).Item2; TempRec(i%).Item3; TempRec(i%).Item4; TempRec(i%).Item5
NEXT

CLOSE #1

And the C++ code i have made (VC++2008, console program)

#include "stdafx.h"
#include "iostream"
#include "fstream"

using namespace std;

//Prototype function declerations
ifstream& OpenRecords();

struct SalesRecord
{
	int Item1, Item2, Item3, Item4,	Item5;
};

int main ()
{
	//Title
	cout << " Employee sales records.\n" << endl;

	//Get the file stream or quit if the records file is not found. 
	ifstream& fileStream = OpenRecords();
	
	// count the number of entries, create array to match and load the data
	cout << "\n Loading records, please wait..." << endl;
	while(!fileStream.eof())
	{		
		//Count or calculate number of entries, create array of SalesRecord struct and store 
		// the data in it
	}
	// Allow the user to see the final screen before exit.
	system("PAUSE");
	return 0;
}

// This function checks for the records files existance, if it exists, returns a pointer to the 
// open file stream, If it does not exist then the program is exited.
ifstream& OpenRecords()
{
	// Make sure the records file exists before running the program
	cout << "\n Welcome, performing record check..." << endl; 
	// Create a pointer to the filename 
	const char* FilePntr = "SalesRecords.txt";
	// Attempt to open the file, if good return pointer of open file stream else report error and exit.
	ifstream* CheckFileStream = new ifstream(FilePntr);
	if (CheckFileStream->good())
	{
		cout << "\n Record file found."<<endl;
	}
	else // Inform of file not found/or empty file and exit the program
	{
		cout << "\n RECORD FILE NOT FOUND!\nTHIS PROGRAM WILL NOW EXIT\n"<<endl;
		delete CheckFileStream;
		system("PAUSE");
		system("EXIT");
	}
	return *CheckFileStream;
}

So what i am aiming to do is,

-Open the file
-Count the number of entries in it (all the same size)
-Create an array to hold the data
-Read it

after that i should be ok, any ideas on getting that far would be great,

Many thanks,

John

It's bad coding to do what openRecords() is doing. The ifstream object should be declared in main then passed by reference to OpenRecord()

int main ()
{
	//Title
	cout << " Employee sales records.\n" << endl;

	//Get the file stream or quit if the records file is not found. 
	ifstream fileStream;
         OpenRecords(fileStream);
	
}


void OpenRecords(ifstream& CheckFileStream)
{
	// Make sure the records file exists before running the program
	cout << "\n Welcome, performing record check..." << endl; 
	// Create a pointer to the filename 
	const char* FilePntr = "SalesRecords.txt";
	// Attempt to open the file, if good return pointer of open file stream else report error and exit.
	CheckFileStream.open(FilePntr);
	if (!CheckFileStream.is_open()) // <<<<<<<<<
	{
		cout << "\n Record file found."<<endl;
	}
	else // Inform of file not found/or empty file and exit the program
	{
		cout << "\n RECORD FILE NOT FOUND!\nTHIS PROGRAM WILL NOW EXIT\n"<<endl;
		system("PAUSE");
		exit(1); // <<<<<< 
	}

}

Thanks for the tip, I will try to remember it.

I have started from scratch to hopefully make it easier for me to learn and for others to help me.

I have 2 questions,

1. How do i get the number of records in a random access file (all records the same size)?

2. How do i get the information from the file into an array of the right structure?

Here's my new code...

// RandomFiles.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "fstream"
#include "iostream"

using namespace std;

struct SalesRecord
{
	int Item1;
	int Item2;
	int Item3;
	int Item4;	
	int Item5;
};

int main()
{
	ifstream CheckFileStream;
	CheckFileStream.open("SalesRecord.txt",ios::binary);

	if (CheckFileStream.is_open())
	{
		cout << "File found, loading records..."<<endl;

		// Calculate number of entries in file based on the size of the SalesRecord structure.
		// int NumberOfRecords = ??;
		
		// Dimesion an array of SalesRecrod Structure to match the number of records.

		//Load the record data into the array. 
		for (int i = 0; i < NumberOfRecords; i++)
		{
						
		}
	}
	else
	{	
		cout << "File not found, exiting..."<<endl;
		system("PAUSE");
		exit(1);
	}

	return 0;
}

Thanks,

John

1. Get the file size and divide by the size of each record. After opening the file, call seekg() to the end of the file, then tellg() to get the file size.

2. You don't need that loop on line 34. If you know the number of records then just use ifstream::read() to read the entire file into an array of structures all at one time. Of course you have to allocate an array of appropriate size beforehand.

I have just achieved part 1, so many thanks for all your hints Ancient Dragon.

This is the usual loop to use:

#include <fstream>
#include <iostream>
#include <vector>
using namespace std;

//define your SalesRecord.

int main() {
  vector<SalesRecord> data; //storage for all the SalesRecords.
  
  ifstream CheckFileStream;
  CheckFileStream.open("SalesRecord.txt",ios::binary);

  if(CheckFileStream.is_open()) {
    SalesRecord tmp; //temporary storage for the one element to be read.
    while(CheckFileStream.read((char*)&tmp, sizeof(SalesRecord))
      data.push_back(tmp); //adds the element to the data.
    CheckFileStream.close();
  } else {
    cout << "File not found, exiting..." << endl;
    return 1;
  };

  return 0; //all went well.
};

The above works because the read function returns a reference to the ifstream which will evaluate to false if it has reached the end of the file. So, as long as the end is not reached, add the last read element to the dynamic array of SalesRecords (the standard C++ thing for a dynamic array is std::vector, as shown).

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.