From: Paul N on
On 24 Mar, 15:40, Piranha <eu_pira...(a)gmx.net> wrote:
> My application uses a config.ini file to store some variables, which
> it saves at the end and reads at program start, such as the content of
> an edit control or the position and size of the window.
> It´s a mixture of values and strings, so to make things easier, I´m
> converting everything to string and write it as plain txt.
> Obviously I needed a separator there, but the strings can contain any
> possible character, so I base64_encode() each piece to make sure there
> can´t be any dots in the string and then I separate the pieces by
> dots.
>
> Over time I´ve added more and more things the program should save in
> there and by now all those conversions have become a huge function.
> I´m losing overview in between 100s of itoa(), WideCharToMultiByte()
> and the always present base64_encode().
> Recently I´m even trying to save a few things that can´t be converted
> to string so easy, like a COLORREF struct, meaning I have to split up
> the struct into its members, and convert all members separate to get
> the string.
>
> I´m wondering, isn´t there an easier way, to read and write the data?
> I´ve considered making 2 files, a config.ini where I save strings in
> txt format and a config.dat where I save the rest binary, but I don´t
> like the idea of 2 separate files there.
>
> Long speech short sense, how can I write a mixture of text and binary
> data into a file, and how can I read the the file again to split up
> the data and convert all pieces back to their types?
>
> I´m not using any kind of MFC or VC or .NET, but only MinGW/GCC++.

One of my earlier programs saved its data simply by writing structs to
a file, the way Scott has suggested, but I found this a pain when I
wanted to add more features. My latest program writes things a bit
like HTML, so that extra features can simply be added. For instance,
the save file includes stuff like:

<title>To do today</title>
<priority=6>
<locked=no>
<created=4/12/2006>

To do this, you need to read and write routines to store data of
different types, though it seems from what you have said above that
you may only need to read and write strings and integers. For
instance:

int writeintvalln(FILE *fp, const char *name, int val) {
_ftprintf(fp, _TEXT("<%hs=%d>\n"), name, val);
return TRUE;
}

If you have suitable routines, you can then write your data like:

writestringtagln(fp, "title", title);
writeintvalln(fp, "priority", priority);
writeflagln(fp, "locked", locked);
writedatevalln(fp, "created", &created);

and read it in by reading a line and seeing what you can do with it,
like:

if (
!isintval(buff, "priority", &priority) &&
!isflagval(buff, "locked", &locked) &&
!isdateval(buff, "created", &created) &&
!isreadstring(buff, "title", title, fp, TITLELEN)
) object to the line being an error

The point is you want to try and abstract what is going on. You don't
want hundreds of itoa(), WideCharToMultiByte() and base64_encode(),
you want only one!

Hope that helps...
Paul.
From: Piranha on
On 24 Mrz., 23:06, Paul N <gw7...(a)aol.com> wrote:
> On 24 Mar, 15:40, Piranha <eu_pira...(a)gmx.net> wrote:
>
>
>
>
>
> > My application uses a config.ini file to store some variables, which
> > it saves at the end and reads at program start, such as the content of
> > an edit control or the position and size of the window.
> > It´s a mixture of values and strings, so to make things easier, I´m
> > converting everything to string and write it as plain txt.
> > Obviously I needed a separator there, but the strings can contain any
> > possible character, so I base64_encode() each piece to make sure there
> > can´t be any dots in the string and then I separate the pieces by
> > dots.
>
> > Over time I´ve added more and more things the program should save in
> > there and by now all those conversions have become a huge function.
> > I´m losing overview in between 100s of itoa(), WideCharToMultiByte()
> > and the always present base64_encode().
> > Recently I´m even trying to save a few things that can´t be converted
> > to string so easy, like a COLORREF struct, meaning I have to split up
> > the struct into its members, and convert all members separate to get
> > the string.
>
> > I´m wondering, isn´t there an easier way, to read and write the data?
> > I´ve considered making 2 files, a config.ini where I save strings in
> > txt format and a config.dat where I save the rest binary, but I don´t
> > like the idea of 2 separate files there.
>
> > Long speech short sense, how can I write a mixture of text and binary
> > data into a file, and how can I read the the file again to split up
> > the data and convert all pieces back to their types?
>
> > I´m not using any kind of MFC or VC or .NET, but only MinGW/GCC++.
>
> One of my earlier programs saved its data simply by writing structs to
> a file, the way Scott has suggested, but I found this a pain when I
> wanted to add more features. My latest program writes things a bit
> like HTML, so that extra features can simply be added. For instance,
> the save file includes stuff like:
>
> <title>To do today</title>
> <priority=6>
> <locked=no>
> <created=4/12/2006>
>
> To do this, you need to read and write routines to store data of
> different types, though it seems from what you have said above that
> you may only need to read and write strings and integers. For
> instance:
>
> int writeintvalln(FILE *fp, const char *name, int val) {
> _ftprintf(fp, _TEXT("<%hs=%d>\n"), name, val);
> return TRUE;
>
> }
>
> If you have suitable routines, you can then write your data like:
>
> writestringtagln(fp, "title", title);
> writeintvalln(fp, "priority", priority);
> writeflagln(fp, "locked", locked);
> writedatevalln(fp, "created", &created);
>
> and read it in by reading a line and seeing what you can do with it,
> like:
>
> if (
>         !isintval(buff, "priority", &priority) &&
>         !isflagval(buff, "locked", &locked) &&
>         !isdateval(buff, "created", &created) &&
>         !isreadstring(buff, "title", title, fp, TITLELEN)
>   ) object to the line being an error
>
> The point is you want to try and abstract what is going on. You don't
> want hundreds of itoa(), WideCharToMultiByte() and base64_encode(),
> you want only one!
>
> Hope that helps...
> Paul.- Zitierten Text ausblenden -
>
> - Zitierten Text anzeigen -

Thanks for the answer, sounds real good, but slightly exceeds my
limited skills.

I´d love to save everything into the file as it is, I´d love to save
structs like COLORREF or RECT in one piece, instead of 3 or 4 separate
int´s, I´d even love to save std::wstring as such or even
std::vector<std::wstring> and I´d also love to have some additional
info in html style.
My only problem is, while the data can contain ANY value and ANY
character, including '\0' or linebreaks, how can I save all that and
read it again so I can separate the data correctly into their
corresponding variables or containers?

Scott´s suggestion I find easy to understand, everything in fixed size
(means all I have to do is convert std::string to char[]) and use a
struct to save it binary in one piece.

Your suggestion sounds better, I already had in mind to put some kind
of index into the data, so the order of things in the file doesn´t
matter anymore, but each piece could be indicated by its index number,
which would allow to add stuff in future in the middle of the data and
keep some kind of sorting order within the file, and would also allow
for different versions of the application to read different versions
of the config file, as long as the index numbers match the data type.

I just don´t know, how to write, (re-)read and separate the pieces of
data in such a case.
From: David Schwartz on
On Mar 24, 10:00 am, "ScottMcP [MVP]" <scott...(a)mvps.org> wrote:

> You can create a struct or class that contains all of the data members
> to be saved.  Something like
>
> struct config
> {
> int structlength;
> int x,y,dx,dy;
> char text[50];
> ...
>
> } theconfig;

No, you can't do that. Files are arrays of bytes and to have a file
format, it must have a defined structure for each byte. If the next
version of his compiler stores 'int's a different way, he won't be
able to read back the files he wrote out.

DS
From: David Schwartz on
On Mar 24, 8:40 am, Piranha <eu_pira...(a)gmx.net> wrote:

> I´m wondering, isn´t there an easier way, to read and write the data?
> I´ve considered making 2 files, a config.ini where I save strings in
> txt format and a config.dat where I save the rest binary, but I don´t
> like the idea of 2 separate files there.

> Long speech short sense, how can I write a mixture of text and binary
> data into a file, and how can I read the the file again to split up
> the data and convert all pieces back to their types?

You could reinvent the wheel if you want. But there are already lots
of solutions to exactly this problem.

http://www.hyperrealm.com/libconfig/
http://liblcfg.carnivore.it/
http://linux.wareseeker.com/Programming/configuration-file-library-1.1.zip/326462

You could define a format that contains a name, a type, and a payload.
You could always include the length in each entry, or you could define
an 'end of entry' character. You can keep the data internally as a
linked list of parameters and also indexed as a hash table if desired.

You can also use XML, X.609 (BER), lines terminated with a newline, or
various other standardized formats.

DS
From: Jonathan de Boyne Pollard on
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
<blockquote
cite="mid:d53d9f85-1fa2-475d-9cd4-8d15e964a4fd(a)r1g2000yqj.googlegroups.com"
type="cite">
<p wrap="">My application uses a config.ini file to store some
variables, [...]&nbsp; such as [...] the position and size of the window
[...] I'm wondering, isn't there an easier way, to read and write the
data?<br>
</p>
</blockquote>
<p><a href="http://support.microsoft.com/kb/310294">Use the registry</a>,
perhaps?&nbsp; <a href="http://www.delphi3000.com./articles/article_852.asp">Like
this</a>.&nbsp; Note the caution in the MSKB article.<br>
</p>
</body>
</html>