-1

my output file has random data when I write something on it,I checked multiple sources of writing object on a file and this seems correct still can't enter the right data

enter image description here


#include<bits/stdc++.h>
using namespace std;
namespace fs = std::filesystem;
class Events{
    char eventName[90];
    
    public:
        void setEventName(){
            cout<<"set event name ";
            cin>>eventName;
        }
        
        
};

class EventFunctions:public Events{
    
public:
        
void WriteEvent(){
        
    Events obj;
    obj.setEventName();
    ofstream outf;
    outf.open("hello.txt");
    outf.write((char *)&obj,sizeof(obj));
    outf.close();
    }
    
};


int main(){

EventFunctions ee;
ee.WriteEvent();        
    
}

using devc++
MinGW GCC 11.2.0

xAdvitya
  • 119
  • 2
  • 12
  • 2
    While you call your file `hello.txt`, you aren't actually creating a text file with your code. Instead you are creating a binary file. – NathanOliver Nov 07 '22 at 19:12
  • 2
    Also, in `EventFunctions::WriteEvent`, you create a new `Events obj;` that's local to the function and has no connection whatsoever to the base class subobject that's part of the `EventFunctions` object. Which I guess is "fine" because you initialize that local variable but... What's going on with the inheritance here? Why is `EventFunctions` a class at all? – Nathan Pierson Nov 07 '22 at 19:14
  • You probably want to change the extension. `hello.dat` would be better Iand perhaps change the base part of the name as "hello" is not descriptive of the purpose of the file. This is not a text file and should not be read with a text editor. – drescherjm Nov 07 '22 at 19:16
  • Shame you don't say what the right data is. I guess you mean without the garbage. That would just be something like `outf << obj.eventName << '\n';`, except that won't compile because `eventName` is private. The basic problem is that you are using binary I/O when (it seems) you want text I/O. – john Nov 07 '22 at 19:37
  • Side note: Seeing `#include` along with `#include ` strongly suggests that you don't know what `#include` does and how to use it. [Here's a link to some reading to help with that](https://stackoverflow.com/q/31816095/4581301). – user4581301 Nov 07 '22 at 19:42
  • @user4581301 I know I was just using it for testing purpose – xAdvitya Nov 07 '22 at 21:13
  • @NathanPierson yea it might seem confusing but I only shared a part of code where I was having issues – xAdvitya Nov 07 '22 at 21:15

2 Answers2

3

There are a couple of issues here. First, write does not stop at a null pointer. It prints exactly as many characters as you ask it to, and that can include the 86 characters of garbage after the \0 terminating your string. You want

outf.write(my_string, strlen(my_string));

But there's more going on here. When you write (char *)&obj, I'm guessing that you're trying to write obj.eventName in a clever way. But you can't do that in this case. From the C++ standard §11.4.1

If a standard-layout class object has any non-static data members, its address is the same as the address of its first non-static data member if that member is not a bit-field. Its address is also the same as the address of each of its base class subobjects.

Now, your class satisfies standard layout, so the address of obj is guaranteed to be the address of obj.eventName. But this is a very arcane and confusing way to write this. And if you're expecting this to somehow automatically serialize the whole class, then that won't work. C++ is free to add or subtract padding in classes, so your class may be slightly more than 90 bytes. And it's not guaranteed to have the same representation across machines or compiler versions, so writing the bytes of a C++ object to disk and then reading them back later is a very bad idea. If your goal is serialization, write a real serializer, rather than hacking together char* casts.

Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116
2

You're writing out the wrong thing. Instead of writing out an object, write out the string that the object contains. And limit the length to the actual length of the string, not the whole buffer with all its uninitialized garbage.

outf.write(&obj.eventName, strlen(obj.eventName));
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622