I'm trying to figure out how to write an int (as a record number) and a string (up to 12 characters) into a binary file. So in one project the binary file is created with all 5 records written to it, with blank data, eg string is empty. In the next project I ask for user input indicating which record to update and what string to store in the file. Then the next project displays only the records that have data stored in them.

The problem I'm having is, I think I'm writing the string to the file incorrectly. When I run the ReadBinaryFile program, it displays the record numbers correctly, but blank data for the string entries. How do I properly store a random-sized string, up to 12 characters into this file? I have posted the files I have as well.

Here is the part where I store the data to the file:

Rivera rivy;
int recordNum;
cin >> recordNum;
...
cout << "Enter word\n? ";
cin >> word;
		
rivy.setKey(recordNum);
rivy.setWord(word, 0, 12);
		
lamefile.seekp((rivy.getKey() - 1) * sizeof(Rivera));

//rivy is a Rivera obj; Rivera object contains an int and a string
lamefile.write(reinterpret_cast<const char*>(&rivy), sizeof(Rivera));
		
cout << "Enter Record Number: (1-5, 0 to quit0\n? ";
cin >> recordNum;

PS: This isn't homework. I am following along in C++ How to Program 5th Ed. There is a code complete exercise in the book. I am trying to do this using strings though, rather than const char*. Since it's giving me trouble, I'm just interested in getting this right while I learn more about strings and fstreams. TIA!

Attachments
#include <iostream>
using std::cerr;
using std::endl;
using std::ios;

#include <fstream>
using std::ofstream;

#include <cstdlib>
using std::exit;

#include "Rivera.h"

int main()
{
	//name of ofstream object
	ofstream lamefile("stringy.bin", ios::binary);
	
	//exit if couldn't create file
	if (!lamefile)
	{
		cerr << "Couldn't Open File." << endl;
		exit(1);
	}
	
	//blank Rivera object
	Rivera blankRivera;
	
	//create 5 blank records
	for (int i=0; i<5; i++)
	{
		lamefile.write(reinterpret_cast<const char*>(&blankRivera), sizeof(Rivera));
	}
	
	return 0;
}
#include <iostream>
using std::cerr;
using std::cout;
using std::endl;
using std::ios;

#include <fstream>
using std::ifstream;
using std::ostream;

#include <cstdlib>
using std::exit;

#include <string>
using std::string;

#include "Rivera.h"

void outputLine(ostream&, const Rivera&);

int main()
{
	ifstream lamefile("stringy.bin", ios::in);
	
	if (!lamefile)
	{
		cerr << "Couldnt open file." << endl;
		exit(1);
	}
	
	cout << "Record Number\t\t\t" << "String" << endl;
	
	Rivera person;
	
	lamefile.read(reinterpret_cast<char *>(&person), sizeof(Rivera));
	
	while (lamefile && !lamefile.eof())
	{
		if (person.getKey() != 0)
			outputLine(cout, person);
		
		lamefile.read(reinterpret_cast<char *>(&person), sizeof(Rivera));
	}
	
	return 0;
}

void outputLine(ostream &output, const Rivera & record)
{
	output << record.getKey()  << "\t\t\t" << record.getWord() << endl;
}
#include <string>
using std::string;

#include "Rivera.h"

Rivera::Rivera()
	: id(0), palabra("")
{
	//empty body
}

//set record num
void Rivera::setKey(const int key)
{
	id = key > 0 ? key : 0;
}

//return record num
int Rivera::getKey() const
{
	return id;
}

//set string
void Rivera::setWord(const string& word)
{
	int start = 0;
	int end = word.length() > 13 ? word.length() : 12;
	string temp(word, start, end);
	palabra = temp;
}

//return string
string Rivera::getWord() const
{
	return palabra;
}
#ifndef RIVERA_H_
#define RIVERA_H_

#include <string>
using std::string;

class Rivera
{
public:
	Rivera();
	
	void setKey(const int);
	int getKey() const;
	
	void setWord(const string&);
	string getWord() const;
	
private:
	int id;
	string palabra;
};
#endif /*RIVERA_H_*/
#include <iostream>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::ios;

#include <fstream>
using std::fstream;

#include <cstdlib>
using std::exit;

#include <string>
using std::string;

#include "Rivera.h"

int main()
{
	fstream lamefile("stringy.bin", ios::in | ios::out | ios::binary);
	
	//exit if fstream cannot open file
	if (!lamefile)
	{
		cerr << "Couldn't Open File." << endl;
		exit(1);
	}
	
	cout << "Enter Record Number: (1-5, 0 to quit)\n? ";
	
	Rivera rivy;
	int recordNum;
	cin >> recordNum;
	
	string word;
	
	while (recordNum > 0 && recordNum <= 5)
	{
		cout << "Enter word\n? ";
		cin >> word;
		
		rivy.setKey(recordNum);
		rivy.setWord(word, 0, 12);
		
		lamefile.seekp((rivy.getKey() - 1) * sizeof(Rivera));
		
		lamefile.write(reinterpret_cast<const char*>(&rivy), sizeof(Rivera));
		
		cout << "Enter Record Number: (1-5, 0 to quit0\n? ";
		cin >> recordNum;
	}
	
	return 0;
}

you can't write std::string objects to a binary file like that. The easiest way to simplify your program is to use a char array instead of std::string. Now in the class constructure initialize that char array to all 0s.

class Rivera
{
public:
	Rivera();
	
	void setKey(const int);
	int getKey() const;
	
	void setWord(const string&);
	string getWord() const;
	
private:
	int id;
	char palabra[13];
};

I see. I guess that's why the book example used a char array as well. Thank You!

This question has already been answered. Start a new discussion instead.