简体   繁体   中英

Can std::wfstream passed by-reference AND will I be able to use write() and read() properly?

I use a self-made error/log-class for my project which is also be able to store/load itself into/from a file. To make it easier for me when handling more objects I want to pass a file stream by-reference to this function which then uses the write/read member of the stream.

Save with:

in.open(L"XError.err",std::ios::in | std::ios::out | std::ios::binary | std::ios::trunc);

Load with:

in.open(L"XError.err",std::ios::in | std::ios::out | std::ios::binary);

For saving:

unsigned int HError::SaveToBufferW(std::wfstream& file)
{
    _ErrorSaveStruct ess = {0};
    ESS.IsUNICODE = true;
    ESS.ItemCount = 9999999;
    file.write((wchar_t*)&ess,sizeof(_ErrorSaveStruct) / sizeof(wchar_t));
    return 0;
}

For loading:

int HError::LoadFromBufferW(std::wfstream& file)
{
    _ErrorSaveStruct ess = {0};
    file.read((wchar_t*)&ess,sizeof(_ErrorSaveStruct) / sizeof(wchar_t));
    return 0;
}

I checked the file and found out that nothing but whitespaces is written. When I read/write a Unicode-string everything works and the string as well is readable in the file.

Edit: here you go

 struct _ErrorSaveStruct
{
    unsigned int MsgSize;
    unsigned int TimeSize;
    unsigned int LastErrorSize;
    int ItemCount;
    int errState;
    bool InitMsg;
    bool IsUNICODE;
};

ok, used another answer to bypass my problem in some way:

int main()
{   
HLib::_ErrorSaveStruct Ess = {0};  // just a namespace
Ess.IsUNICODE = true;
Ess.errState = 100;
Ess.ItemCount = 9999;

wchar_t* StringTest[1] = {L"WOORD"};    // same like (wchar_t[5])

FILE* iobuf = NULL;

// create new in binary read-write mode
if (_wfopen_s(&iobuf,L"WTest.err",L"wb+")==0) 
{
        //WRITING BLOCK
    if (fwrite(&Ess,sizeof(Ess),1,iobuf) != 1)  // sizeof_ErrorSaveStruct
        std::cout << "Fail (Reading struct)";

    if (fwrite(StringTest,sizeof(wchar_t) * 5,1,iobuf) != 1) // size = 5 
        std::cout << "Fail (Reading string)";

    // reset content
    SecureZeroMemory(&Ess,sizeof(Ess));
    SecureZeroMemory(StringTest,sizeof(wchar_t)*5);

    fseek(iobuf,0,0); // rewind
    fflush(iobuf);    // flush because you switch from write to read

     /// READING BLOCK
    if (fread(&Ess,sizeof(Ess),1,iobuf) != 1)   // sizeof_ErrorSaveStruct
        std::cout << "Fail (Reading struct)";

    if (fread(StringTest,sizeof(wchar_t) * 5,1,iobuf) != 1) // size = 5 
        std::cout << "Fail (Reading string)";
    fclose(iobuf);
}

return 0;

I really learned something about streams and file IO. Thinking of other solutions, i also could have passed single parameters (int,bool) to wfstream instead of a whole struct. It would have been possible as well to use std::fstream with binary flag set and pass a wchar_t string via write(). Anyway, this solution works well enough for me and I'm really happy about that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM