1

I'm writing a small back-end in cpp where I have to write some crossword data into a binary file. I have created an XWPuzzle class with all its data members public, and xWord is an object of this class. Here is the piece of code with which I'm trying to write to the binary file:

#include"binIncludes.h"

int main(int argc, char** argv)
{
    cout<<"Bin read-write Tester\n";
    xWord.title="Yeah!\0";
    xWord.author="Nobody\0";
    xWord.grid=147;
    xWord.userGrid=109;
    xWord.clues[0]="as\0";
    xWord.clues[1]="de\0";
    xWord.clues[2]="re\0";
    xWord.solution[0]="ASSET\0";
    xWord.solution[1]="DEER\0";
    xWord.solution[2]="REED\0";
    xWord.checksum=(int)(xWord.title.at(0))+(int)(xWord.author.at(0))+xWord.grid+xWord.userGrid;
    xWord.checksum+=(int)(xWord.clues[0].at(0))+(int)(xWord.clues[1].at(0))+(int)(xWord.clues[2].at(0));
    xWord.checksum+=(int)(xWord.solution[0].at(0))+(int)(xWord.solution[1].at(0))+(int)(xWord.solution[2].at(0));
    fstream file;
    file.open("binTest.bin",ios::out|ios::binary);
    file.write(SIGNATURE,sizeof(SIGNATURE));
    file.write(VERSION,sizeof(VERSION));
    file.write(TYPE,sizeof(TYPE));
    file.write((char*)xWord.checksum,sizeof(xWord.checksum));
    file.write(xWord.title.c_str(),xWord.title.size());
    file.write(xWord.author.c_str(),xWord.author.size());
    file.write((char*)xWord.grid,sizeof(xWord.grid));
    file.write((char*)xWord.userGrid,sizeof(xWord.userGrid));
    file.close();
    cout<<"File written\n";
    _getch();
    return 0;
}

SIGNATURE, VERSION and TYPE are null-terminated strings, but the compiled program throws an error when it gets to the line

file.write((char*)xWord.checksum,sizeof(xWord.checksum));

The debugger throws a First-chance exception (Access Violation reading location error) at MSVCR100.dll. Am I doing something wrong by using a member of a class the wrong way? This is an independent project and not any homework. I've been running around for this for two days now. Any specific help appreciated. Thanks.

I have other data to be written also, in addition to those from this class.

EDIT:

XWPuzzle.h:

#ifndef XWPULZZLE_H
#define XWPUZZLE_H

#include"binIncludes.h"

class XWPuzzle
{
    public:
        string title;
        string author;
        int grid;
        int userGrid;
        string clues[3];
        string solution[3];
        int checksum;
} xWord;

#endif

binDefines.h:

#ifndef BIN_DEFINES_H
#define BIN_DEFINES_H

#include"binIncludes.h"

#define SIGNATURE "BinFile\0"
#define VERSION "0.1.1\0"
#define TYPE "With Solution\0"

#endif

binIncludes.h:

#ifndef BIN_INCLUDES_H
#define BIN_INCLUDES_H

#include<iostream>
#include<conio.h>
#include<string>
#include<fstream>

using namespace std;

#include"binDefines.h"
#include"XWPuzzle.h"

#endif
artfuldev
  • 1,118
  • 1
  • 13
  • 25
  • We need to see `XWPuzzle`'s declaration at least. – Kiril Kirov Apr 08 '13 at 06:35
  • Where is xWord object made? and I wanna see your class declaration. – Kyokook Hwang Apr 08 '13 at 06:37
  • Sorry for the delay. I've added the XWPuzzle's declaration. – artfuldev Apr 08 '13 at 06:54
  • 1
    The fun you'll have, unless they are fixed size strings, is reading them back. A simple way to handle that is to write the length first, then the string data and you'll know how much to read back. – Retired Ninja Apr 08 '13 at 07:05
  • 1
    Isn't that why they are NUL-terminated strings? I thought that was why nul-terminated strings were used. – artfuldev Apr 08 '13 at 07:08
  • The array of characters returned by `string.c_str()` is null-terminated, but the value returned by `string.size()` only includes the number of actual characters in the string not including the terminator. – Retired Ninja Apr 08 '13 at 07:16
  • No reason for the code given for this to crash, your problem must be somewhere else. Sounds a bit like memory corruption or a NULL pointer error but would need to see all the code to tell. But as Retired Ninja says you aren't going to be able to read these strings back because you've lost the size of the string. – john Apr 08 '13 at 07:40
  • I'm ready to provide all code, which is no more than a 4 short files. Also, will using string.size()+1 fix the prob? – artfuldev Apr 08 '13 at 08:08
  • Yes, string does have the size() function. I could also try with length(). After another analysis the exception seems to occur at the first usage of a class member, not the string. I have edited the question. – artfuldev Apr 08 '13 at 08:26

1 Answers1

1

You are casting integer to a pointer and trying to write data by this pointer. That's wrong. You shoud get pointer to a checksum, cast it and then write

file.write((char*)(&xWord.checksum),sizeof(xWord.checksum));

Same with grid and userGrid fields

Jeka
  • 1,364
  • 17
  • 33