Hello,

I need help to try and figure out why one of my functions does not write to the file. I have 4 functions (below) and all of them write to the file except the updateRecord function. I know this is the case because I keep checking the .dat file and also because I keep hitting option 1 which is to print, the printTextFile() function, which prints all the records. When I add and delete a record it works, but for the updateRecord it will update it on the screen but not the actual text file.

printTextFile(fstream&);
updateRecord(fstream&);
newRecord( fstream& );
deleteRecord( fstream& );

Also, I was wondering, once I write to a file shouldn't the file stay in existence even when the program ends?

My functions are as follow:

// create formatted text file for printing
void Tools::printTextFile(fstream &readFromFile )
{
	// create text file                            
    ofstream outPrintFile( "print.txt", ios::out );

    // exit program if ofstream cannot create file
    if ( !outPrintFile )
    {
       cerr << "File could not be created." << endl;
       exit( 1 );
    } // end if


	// print header in the test file (formatted this way to easily view)
    outPrintFile << left << setw(10) << "Tool Id" 
		         << right << setw(10)<< " Tool Name" 
				 << right << setw(20) << "Quantity" 
				 << right << setw(20) << " Unit Price" << endl; 

	// print header in the output prompt screen
	printHeader();

    // set file-position pointer to beginning of readFromFile
    readFromFile.seekg( 0 );                                 

    // read first record from record file
	Tools tool;
    readFromFile.read( reinterpret_cast < char * >( &tool ),
       sizeof ( Tools ) );                               

    // copy all records from record file into text file
    while ( !readFromFile.eof() )
    {
       // write single record to text file
       if ( tool.getPartNumber() != 0 ) // skip empty records
          outputLine( outPrintFile, tool );

       // read next record from record file                      
       readFromFile.read( reinterpret_cast < char * >( &tool),
          sizeof ( Tools ) );                               
    } // end while
} 









 // update the new quantity and unit price in the record
void Tools::updateRecord( fstream &updateFile )
 {
    // obtain number of account to update
	 int partNumber = getPart( "\nEnter tool part identification number to update: " );

    // move file-position pointer to correct record in file           
    updateFile.seekg( ( partNumber - 1 ) * sizeof ( Tools ) );

    // read first record from file
    Tools tool;
    updateFile.read( reinterpret_cast < char * >( &tool ),
       sizeof( Tools ) );                              

    // update record
    if ( tool.getPartNumber() != 0 )
    {
       printHeader();  
       outputLine( updateFile, tool ); // display the record

       // request user to specify new quantity
       cout << "\nEnter new current quantity: ";
       int currentQuantity;							// change the quantity
       cin >> currentQuantity;
       tool.setInStock( currentQuantity );			// update record 
     		
       // request user enter a new unit price
       cout << "Enter new unit price for the tool: ";
       double currentPrice; // change the unit price
       cin >> currentPrice;
	   tool.setUnitPrice( currentPrice );			// update record

	   cout << "\nPart # " << partNumber << " has been updated.\n";

	   	// print header in the output prompt screen
		printHeader();

       outputLine( updateFile, tool ); // display the record


       // move file-position pointer to correct record in file           
       updateFile.seekp( ( partNumber - 1 ) * sizeof( Tools ) ); 

	   // write updated record over old record in file               
       updateFile.write( reinterpret_cast < const char * >( &tool ),
          sizeof( Tools ) );


    } // end if
    else // display error if account does not exist
       cerr << "\nPart identification # " << partNumber << " has no information." << endl;
} // end function updateRecord








// create and insert record
void Tools::newRecord( fstream &insertInFile )
{
    // obtain number of account to create
	int partNumber = getPart( "\nEnter new part number: " );
	validatePartNumber(partNumber);

    // move file-position pointer to correct record in file
    insertInFile.seekg( ( partNumber - 1 ) * sizeof( Tools ) );

    // read record from file
    Tools tool;
    insertInFile.read( reinterpret_cast < char * >( &tool ),
       sizeof( Tools ) );                                

    // create record, if record does not previously exist
    if ( tool.getPartNumber() == 0 )
   {
		// user enters tool name, quantity and unit price
		cout << "Enter the tool name: ";
		fflush(stdin);
		cin.getline( toolName, 20, '\n' );
	   
		cout << "Enter the quantity in stock: "; 
		cin >> inStock;
		cout << "Enter the unit price: ";
		cin >> unitPrice;

		// set the record for the part number, tool name, quantity in stock, and unit price
		tool.setPartNumber( partNumber );
		tool.setToolName( toolName );
		tool.setInStock( inStock );
		tool.setUnitPrice( unitPrice );


       // move file-position pointer to correct record in file             
       insertInFile.seekp( ( partNumber - 1 ) * sizeof( Tools ) ); 

       // insert record in file                                         
       insertInFile.write( reinterpret_cast < const char * >( &tool ),
          sizeof( Tools ) );                                       
    } // end if
    else // display error if account already exists
       cerr << "\n\nPart # " << partNumber << " already contains information." << endl;
} // end function newRecord








// delete an existing record
void Tools::deleteRecord( fstream &deleteFromFile )
{
    // obtain number of account to delete
	int partNumber = getPart( "Enter the tool to delete: " );

   // move file-position pointer to correct record in file               
    deleteFromFile.seekg( ( partNumber - 1 ) * sizeof( Tools ) ); 

   // read record from file
   Tools tool;
    deleteFromFile.read( reinterpret_cast < char * >( &tool ),
       sizeof( Tools ) );                                  

    // delete record, if record exists in file
    if ( tool.getPartNumber() != 0 )
    {
       Tools blankTool(0); // create blank record

       // move file-position pointer to correct record in file
       deleteFromFile.seekp( ( partNumber - 1 ) *          
          sizeof( Tools ) );                             

       // replace existing record with blank record         
       deleteFromFile.write(                                
          reinterpret_cast < const char * >( &blankTool ),
          sizeof( Tools ) );                           

       cout << "\nPart # " << partNumber << " deleted.\n";
    } // end if
    else // display error if record does not exist
       cerr << "\nPart # " << partNumber << " is empty.\n";
} // end deleteRecord








// display single record
void Tools::outputLine(ostream &output, const Tools &record )
{
	output << left << setw(10 ) << record.getPartNumber() 
		<< setw( 16 ) << record.getToolName() 
		<< right << setw(9) << record.getInStock()
        << right << setw(15) << setprecision(2) << fixed << showpoint << record.getUnitPrice() << endl;

    cout << left << setw(10) << record.getPartNumber() 
		<< setw( 16 ) << record.getToolName() 
		<< right << setw(12) << record.getInStock()
        << right<< setw(15) << setprecision(2) << fixed << showpoint << record.getUnitPrice() << endl;
}

Hi,
This code is too difficult to read. Can you please post a well formatted-indented code with code type specified as c++? and also post the entire code including the 'main'. I tried going through this but its just giving me a headache.

Hi,
This code is too difficult to read. Can you please post a well formatted-indented code with code type specified as c++? and also post the entire code including the 'main'. I tried going through this but its just giving me a headache.

Ok it’s a lot of code that’s why I avoided pasting the entire thing but I am curious as to how I can fix the following:

1) I don’t know how to clear the getline() function in order to clear and allow for a fresh tool name for the next record
2) Its printing the padded characters in my array
My print screen is attached as a reference for the issues.

Also
3) I still have the same issue with the updateRecord function() where it’s not writing to the file, yet my other functions do and I cannot see what I am doing different.

Below is my code:

My header file:

class Tools
{
public:
Tools(int = -1, string = "", int = 0, double = 0.0);	// default tools constructor
	// accessor functions for partNumber, toolName, inStock, unitPrice
	void setPartNumber(int);
	int getPartNumber() const;
	void validatePartNumber(int);

	void setToolName(string);
	string getToolName() const;

	void setInStock(int);
	int getInStock() const;

	void setUnitPrice(double);
	double getUnitPrice() const;

	void createAndInitializeTextFile();
	void enterRecords();
	bool test();
	void printHeader();

	void processChoice();
	int enterChoice();

	void printTextFile(fstream&);
	void updateRecord(fstream&);
	void newRecord( fstream& );
	void deleteRecord( fstream& );
	void outputLine( ostream&, const Tools & );
	int getPart( const char * const );

private:
	enum Choices { PRINT = 1, UPDATE, NEW, DELETE, END };
	int partNumber;  // part id number is the record number (record key)
	char toolName[20];		// tool name
	int inStock;		// in stock
	double unitPrice;		// price per unit
}; // end class Tools

.cpp with member function definitions:

// include definition of class Tools from Tools.h
#include "Tools.h"

// default Tools constructor
Tools::Tools( int partNumberValue,string toolNameValue, int inStockValue, double unitPriceValue)
{
	setPartNumber( partNumberValue);
	setToolName( toolNameValue );
	setInStock( inStockValue);
                setUnitPrice( unitPriceValue );
} // end Tools constructor

int Tools::getPartNumber() const
{
    return partNumber;
} 

void Tools::setPartNumber( int partNumberValue)
{
   partNumber = partNumberValue; 
} 

void Tools::validatePartNumber(int checkPart)
{
    if(checkPart > 0 && checkPart <= 100)
	partNumber = checkPart;
    else
    {
           bool flag = false;
           while(flag == false)
          {
	cout << "Part number is a record, an integer within range 1 to 100.";
	cout << "\nRe-enter tool identification number (1 to 100, 0 to end input)\n? ";
	cin >> checkPart;

	if(checkPart > 0 && checkPart <= 100)
	{
	     partNumber = checkPart;
	     flag = true;
	} // end while loop
       } // end if 
} // end function

string Tools::getToolName() const
{
   return toolName;
} 

void Tools::setToolName(string toolNameString)
{
    const char *toolNameValue = toolNameString.data();
    int length = int(toolNameString.size());
    length = (length < 20 ? length : 19);
    strncpy(toolName, toolNameValue, length);
    //toolName[ length ] = '\0'; // append null character to lastName
} 

int Tools::getInStock() const
{
    return inStock;
} 

void Tools::setInStock( int inStockValue)
{
   inStock= inStockValue; 
} 

double Tools::getUnitPrice() const
{
    return unitPrice;
} 

void Tools::setUnitPrice( double unitPriceValue )
{
    unitPrice = unitPriceValue;
} 

void Tools::printHeader()
{
    cout << left << setw(10) << "\nTool Id" 
           << left << setw(15)<< " Tool Name" 
           << right << setw(20) << "Quantity" 
           << right << setw(16) << "Unit Price" << endl; 
}

void Tools::createAndInitializeTextFile()
{
     ofstream outTools( "hardware.dat", ios::out | ios::binary );

    if ( !outTools )
    {
        cerr << "File could not be opened." << endl;
        exit( 1 );
    } 

   Tools blankTool(0); // constructor zeros out each data member

   // output 100 blank records to file
   for ( int i = 0; i < 100; i++ )
      outTools.write( reinterpret_cast < const char * >( &blankTool ), sizeof ( Tools ) );    
}

void Tools::enterRecords()
{
    fstream outTools( "hardware.dat", ios::in | ios::out | ios::binary );

    // exit program if fstream cannot open file
    if ( !outTools )
    {
         cerr << "File could not be opened." << endl;
         exit( 1 );
    } // end if


      // require user to specify a tool identification number
      cout << "Enter tool identification number (1 to 100, 0 to end input): ";
      cin >> partNumber;
    
     Tools tool; // create the object

      // user enters information, which is copied into file
      while (partNumber != 0)
      {
	validatePartNumber(partNumber);

	// user enters tool name, quantity and unit price
	cout << "Enter the tool name: ";
	//cin >> toolName;
	//setToolName(toolName);
	fflush(stdin);
	cin.getline( toolName, 20, '\n' );
		
	   
                cout << "Enter the quantity in stock: "; 
	cin >> inStock;
	cout << "Enter the unit price: ";
	cin >> unitPrice;

	// set the record for the part number, tool name, quantity in stock, and unit price
	tool.setPartNumber( partNumber );
	tool.setToolName( toolName );
	tool.setInStock( inStock );
	tool.setUnitPrice( unitPrice );

	// seek position in file of user-specified record   
	outTools.seekp( ( tool.getPartNumber() - 1 ) * sizeof ( Tools ) );                         

	// write user-specified information in file                   
	outTools.write( reinterpret_cast < const char * >( &tool ),sizeof ( Tools) );     
                             
	//enable user to enter another account
	cout << "\nEnter tool identification number (1 to 100, 0 to end input): ";
	cin >> partNumber;

         } // end while loop

} // end enterRecords function

bool Tools::test()
{
      Tools tool;
      bool answer = false;
	
      ifstream inTools( "hardware.dat", ios::in | ios::binary );

      // exit program if ifstream cannot open file
      if ( !inTools )
      {
	answer = false;
	cerr << "File could not be opened." << endl;
	exit( 1 );
      } // end if
      else
      {
           answer = true;
      }
          return answer;
}

void Tools::processChoice()
{
     // open file for reading and writing                                  
     fstream inOutTools( "hardware.dat", ios::in | ios::out | ios::binary );

     // exit program if fstream cannot open file
     if ( !inOutTools )
     {
        cerr << "File could not be opened." << endl;
        exit ( 1 );
     } // end if


      int choice; // store user choice

      // enable user to specify action
      while ( ( choice = enterChoice() ) != END )
      {
       switch ( choice )
       {
           case PRINT: // create text file from record file
              printTextFile( inOutTools );
              break;
           case UPDATE: // update record
              updateRecord( inOutTools );
              break;
           case NEW: // create record
              newRecord( inOutTools );
              break;
           case DELETE: // delete existing record
              deleteRecord( inOutTools );
              break;
          default: // display error if user does not select valid choice
              cerr << "Incorrect choice" << endl;
              break;
         } // end switch

         inOutTools.clear(); // reset end-of-file indicator
      } // end while
}


int Tools::enterChoice()
{
     // display available options
     cout << "\nEnter your choice:" << endl
        << "1 - store a formatted text file of accounts - called \"print.txt\" for printing." 
        << endl
        << "2 - update an account" << endl
        << "3 - add a new account" << endl
        << "4 - delete an account" << endl
        << "5 - end program\n? ";

     int menuChoice;
     cin >> menuChoice; 
     return menuChoice;
} 


void Tools::printTextFile(fstream &readFromFile )
{
     // create text file                            
    ofstream outPrintFile( "print.txt", ios::out );

    // exit program if ofstream cannot create file
    if ( !outPrintFile )
    {
       cerr << "File could not be created." << endl;
       exit( 1 );
    } // end if


     // print header in the test file (formatted this way to easily view)
    outPrintFile << left << setw(10) << "Tool Id" 
                     << right << setw(10)<< " Tool Name" 
	     << right << setw(20) << "Quantity" 
	     << right << setw(20) << " Unit Price" << endl; 

      // print header in the output prompt screen
      printHeader();

    // set file-position pointer to beginning of readFromFile
    readFromFile.seekg( 0 );                                 

    // read first record from record file
    Tools tool;

    readFromFile.read( reinterpret_cast < char * >( &tool ),
       sizeof ( Tools ) );                               

    // copy all records from record file into text file
    while ( !readFromFile.eof() )
    {
       // write single record to text file
       if ( tool.getPartNumber() != 0 ) 
          outputLine( outPrintFile, tool );

       // read next record from record file                      
       readFromFile.read( reinterpret_cast < char * >( &tool),
          sizeof ( Tools ) );                               
    } // end while
} 


void Tools::updateRecord( fstream &updateFile )
 {
    // obtain number of account to update
	 int partNumber = getPart( "\nEnter tool part identification number to update: " );

    // move file-position pointer to correct record in file           
    updateFile.seekg( ( partNumber - 1 ) * sizeof ( Tools ) );

    // read first record from file
    Tools tool;
    updateFile.read( reinterpret_cast < char * >( &tool ),
       sizeof( Tools ) );                              

    // update record
    if ( tool.getPartNumber() != 0 )
    {
       printHeader();  
       outputLine( updateFile, tool ); // display the record

       // request user to specify new quantity
       cout << "\nEnter new current quantity: ";
       int currentQuantity;						     
       cin >> currentQuantity;
       tool.setInStock( currentQuantity );			
     		
       // request user enter a new unit price
       cout << "Enter new unit price for the tool: ";
       double currentPrice; 
       cin >> currentPrice;
       tool.setUnitPrice( currentPrice );			
       cout << "\nPart # " << partNumber << " has been updated.\n";

	// print header in the output prompt screen
		printHeader();

       outputLine( updateFile, tool ); // display the record


       // move file-position pointer to correct record in file           
       updateFile.seekp( ( partNumber - 1 ) * sizeof( Tools ) ); 

       // write updated record over old record in file               
       updateFile.write( reinterpret_cast < const char * >( &tool ),
          sizeof( Tools ) );


    } 
    else // display error if account does not exist
       cerr << "\nPart identification # " << partNumber << " has no information." << endl;

} // end function updateRecord



void Tools::newRecord( fstream &insertInFile )
{
    // obtain number of account to create
    int partNumber = getPart( "\nEnter new part number: " );
    validatePartNumber(partNumber);

    // move file-position pointer to correct record in file
    insertInFile.seekg( ( partNumber - 1 ) * sizeof( Tools ) );

    // read record from file
    Tools tool;
    insertInFile.read( reinterpret_cast < char * >( &tool ),
       sizeof( Tools ) );                                

    // create record, if record does not previously exist
    if ( tool.getPartNumber() == 0 )
   {
       // user enters tool name, quantity and unit price
       cout << "Enter the tool name: ";
       fflush(stdin);
       cin.getline( toolName, 20, '\n' );
	   
       cout << "Enter the quantity in stock: "; 
       cin >> inStock;
       cout << "Enter the unit price: ";
       cin >> unitPrice;

       // set the record for the part number, tool name, quantity in stock, and unit price
       tool.setPartNumber( partNumber );
       tool.setToolName( toolName );
       tool.setInStock( inStock );
       tool.setUnitPrice( unitPrice );


       // move file-position pointer to correct record in file             
       insertInFile.seekp( ( partNumber - 1 ) * sizeof( Tools ) ); 

       // insert record in file                                         
       insertInFile.write( reinterpret_cast < const char * >( &tool ),
          sizeof( Tools ) );                                       
    } // end if
    else // display error if account already exists
       cerr << "\n\nPart # " << partNumber << " already contains information." << endl;
} // end function newRecord



void Tools::deleteRecord( fstream &deleteFromFile )
{
    // obtain number of account to delete
    int partNumber = getPart( "Enter the tool to delete: " );

   // move file-position pointer to correct record in file               
    deleteFromFile.seekg( ( partNumber - 1 ) * sizeof( Tools ) ); 

   // read record from file
   Tools tool;
    deleteFromFile.read( reinterpret_cast < char * >( &tool ),
       sizeof( Tools ) );                                  

    // delete record, if record exists in file
    if ( tool.getPartNumber() != 0 )
    {
       Tools blankTool(0); // create blank record

       // move file-position pointer to correct record in file
       deleteFromFile.seekp( ( partNumber - 1 ) *          
          sizeof( Tools ) );                             

       // replace existing record with blank record         
       deleteFromFile.write(reinterpret_cast < const char * >( &blankTool ),
          sizeof( Tools ) );                           

       cout << "\nPart # " << partNumber << " deleted.\n";
    } // end if
    else // display error if record does not exist
       cerr << "\nPart # " << partNumber << " is empty.\n";
} // end deleteRecord


void Tools::outputLine(ostream &output, const Tools &record )
{
   output << left << setw(10 ) << record.getPartNumber() 
        << setw( 16 ) << record.getToolName() 
        << right << setw(9) << record.getInStock()
        << right << setw(15) << setprecision(2) << fixed << showpoint 
        << record.getUnitPrice() << endl;

    cout << left << setw(10) << record.getPartNumber() 
     << setw( 16 ) << record.getToolName() 
     << right << setw(12) << record.getInStock()
     << right<< setw(15) << setprecision(2) << fixed << showpoint 
     << record.getUnitPrice() << endl;
} 


int Tools::getPart( const char * const prompt )
{
    int partNumber;

    // obtain part identification number value
    do
    {
       cout << prompt << " (1 - 100): ";
       cin >> partNumber;
    } while ( partNumber < 1 || partNumber > 100 );
    return partNumber;
}

.cpp file with main() :

#include "Tools.h"

int main()
{
	Tools tool;
	tool.createAndInitializeTextFile();
	tool.enterRecords();	

	if(tool.test())
	{
		cout << "\nHardware program successful.\n";		
		tool.processChoice();
	}
	else
	{
		cout <<"\nHardware program failed.\n";
	}

	cout << endl;
	return 0;
}

Why dont you use these kinds of code tags to easily reference your problem?

Edited 3 Years Ago by happygeek: fixed formatting

this is much better but unfortunately i could not make out y the update is not happening correctly... my suspicion is on 'seekp' but i have no way to be sure ... we'll have to wait for someone else ....

This article has been dead for over six months. Start a new discussion instead.