Converting from an array of wchar_t's to float?!
*sigh*
This is probably going to destroy all hopes of me ever getting considered for a (programming) position at Telltale, but whatever.
I'm trying to load a floating point number from a file that's been stored as an array of wchar_t's.
Here's my code:
Guess what? Both the MessageBox and the console output from LoadGame() claims that X is equal to 53. But it's not! What's stored in the file is 57.9322.
The console output from ReadLine confirms that this is the number being read from the file. It seems to me that lexical_cast() is rounding down the number somehow. But I can't figure out how to fix it!
Anyone who can gets a cookie!
This is probably going to destroy all hopes of me ever getting considered for a (programming) position at Telltale, but whatever.
I'm trying to load a floating point number from a file that's been stored as an array of wchar_t's.
Here's my code:
// LoadTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include "OSFDlg.h"
#include <assert.h>
using namespace std;
template <typename Target, typename Source>
Target lexical_cast(Source source)
{
Target target;
std::ostringstream os;
os << source;
std::istringstream is(os.str());
is >> target;
return target;
}
struct Save
{
wchar_t *LevelName;
float X, Y, Z;
};
wchar_t *LoadDiag()
{
//Filter
TCHAR szFilter[] = TEXT("Save Files (*.SAV)\0*.sav\0");
//Default Extension
TCHAR szDefExtension[] = TEXT("sav\0");
COSFDialog LoadDiag;
if(LoadDiag.FileOpenDlg(szFilter, szDefExtension, TEXT("Load Game"), false))
return (wchar_t*)LoadDiag.GetFileName();
}
wchar_t* ReadLine(wifstream *Stream)
{
wchar_t *Line = new wchar_t[256];
wchar_t ControlChar = '0';
int i = 0;
while(ControlChar != '\n')
{
ControlChar = Stream->get();
wcout << ControlChar;
Line[i] = ControlChar;
i++;
if(i == 256)
break;
}
return Line;
}
__declspec(dllexport) Save* LoadGame(wchar_t* LoadPath)
{
wifstream LoadStream(LoadPath, ios::in);
wchar_t *X = new wchar_t[100];
wchar_t Y;
wchar_t Z;
static Save NewSave;
NewSave.LevelName = new wchar_t[100];
NewSave.LevelName = ReadLine(&LoadStream);
//LoadStream >> X;
X = ReadLine(&LoadStream);
NewSave.X = lexical_cast<float, wchar_t>(*X);
LoadStream >> Y;
NewSave.Y = lexical_cast<float, wchar_t>(Y);
LoadStream >> Z;
NewSave.Z = lexical_cast<float, wchar_t>(Z);
LoadStream.close();
wstringstream WSS;
WSS << NewSave.X;
cout << "\nX: " << NewSave.X;
//Prints the number 53!
MessageBox(NULL, (LPCWSTR)WSS.str().c_str(), TEXT("LoadGame()"), MB_OKCANCEL);
return &NewSave;
}
Guess what? Both the MessageBox and the console output from LoadGame() claims that X is equal to 53. But it's not! What's stored in the file is 57.9322.
The console output from ReadLine confirms that this is the number being read from the file. It seems to me that lexical_cast() is rounding down the number somehow. But I can't figure out how to fix it!
Anyone who can gets a cookie!
Sign in to comment in this discussion.
Comments
Go me!
...I have only a vague idea of what streams are.
I KNEW it had something to do with water!
I'm not 'trying' anything. It's for a school project, actually. I've been programming for a long time, but I have limited experience with C++, unfortunately.
I'll think about looking for an XML serializer... but it sounds a bit overkill for what I'm trying to do. I'm writing a SaveGame dll for UDK (Unreal Development Kit).
I'm not sure how much data you have to save, but if it's a tree-structure then you'll probably be done faster using an XML serializer than if you try serializing yourself. If it's a flat list, then it's really just a matter of personal preference.
Streams are like... uhm... kinda like streams of water. But they can only float one way, depending on what implementation you're working with.
Usually, you start out at the beginning of a stream and read your way forward. Being able to seek back to the beginning after you've read something is a luxury, but is sometimes required to read specific fileformats.
Streams can also be used to write something, but that is usually a separate implementation. I.E There is usually a ReadStream and a WriteStream implementation.
Some writing streams also allow you to seek, but if you seek back after you've written something, you'll write over something you've written before. I.E if you want to write something to a file (for instance) after you've written something else, the usual way of doing that is to fill the file with temporary data from whatever position you want to write to, to the X number of bytes that you want to write after the fact. Then you continiue to write something else, and then you can simply seek back to the original position after the fact and replace the temporary data with something meaningful.
A useful mental model for a stream could be that of the head (tip) of an old fashioned record-player. Usually it just reads the record, but sometimes when working with streams you can (and are required to) jump backwards and forwards at will.
Basically it means taking a normal programming language and make it behave like a shell script with pipes.
P.S. In case you haven't notice, I come from the C school of programming and some of the stuff that C++ does still seems very weird to me.
I've dabbled in programming. Only in C, though. Not C++. Haven't gotten very far. It still intrigues me and I want to get further in it, though. I wrote a small menu launcher program in DOS for my old 486 and its games. That was fun.
I'm obviously out of my element here. I haven't even figured out how to make my TOC work with Calibre because I don't get how XPath works. I can't even imagine what programming something would be like.
... I have played the Star Wars game where you program droids, does that count?
You'd loose precision the same way as you do with XML serialization, but it would work. Aside from that you can of course actually write out the float itself, but that's rarely a good idea...