Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » Community » Newbie corner » Ini file
Ini file [message #58095] Sun, 13 February 2022 18:57 Go to next message
Silvan is currently offline  Silvan
Messages: 56
Registered: December 2014
Location: Trento (IT)
Member
Hello!

Another newby question.

I read the examples of usage of ini file, and I read the source ini.cpp.
I don't find a method to Save the ini file. Have I to do it?
It would be useful (for me) to have an example of defining, reading, modifing and writing an ini file.

Thank you
Silvan
Re: Ini file [message #58096 is a reply to message #58095] Mon, 14 February 2022 07:49 Go to previous messageGo to next message
jjacksonRIAB is currently offline  jjacksonRIAB
Messages: 219
Registered: June 2011
Experienced Member
// contains key value pairs for ini file
VectorMap<String, String> kv = GetIniKeys();

// add a new key
kv.Add("testing", "new key");

// replace an existing key's value
kv.GetPut("text") = "non-default text";

// remove an existing key
kv.RemoveKey("number");

FileOut out("test.ini");

// write pairs to disk
for(KeyValueRef pair : ~kv) {
    out << Format("%s=%s\n", pair.key, pair.value);
}

[Updated on: Mon, 14 February 2022 07:50]

Report message to a moderator

Re: Ini file [message #58105 is a reply to message #58096] Tue, 15 February 2022 20:29 Go to previous messageGo to next message
Silvan is currently offline  Silvan
Messages: 56
Registered: December 2014
Location: Trento (IT)
Member
Thank you, I suppose that makes almost unuseful ini.cpp Smile

ps: what is pair?

That does not work:

template <class T>
class pair {
T &key, &value;
};

[Updated on: Tue, 15 February 2022 21:25]

Report message to a moderator

Re: Ini file [message #58106 is a reply to message #58105] Wed, 16 February 2022 10:24 Go to previous messageGo to next message
jjacksonRIAB is currently offline  jjacksonRIAB
Messages: 219
Registered: June 2011
Experienced Member
In a dictionary, map and other associative containers, both elements together (key and value) are commonly called key-value pairs, or a pair for short.

>that does not work

I'm assuming you looked up KeyValueRef and tried to roll your own?

template <class K, class V>
struct KeyValueRef {
    const K& key;
    V&       value;
    KeyValueRef(const K& key, V& value) : key(key), value(value) {}
};


The reason your version doesn't work is because references *must* be initialized at time of creation, they cannot be nullptr and they cannot be changed to point to something else. That's one of the major differences between a reference and a pointer - so if you look at the code above you'll see that in the constructor those references are being initialized at key(key), value(value). That's why that version works and yours doesn't.

[Updated on: Wed, 16 February 2022 10:47]

Report message to a moderator

Re: Ini file [message #58109 is a reply to message #58095] Wed, 16 February 2022 11:58 Go to previous messageGo to next message
Silvan is currently offline  Silvan
Messages: 56
Registered: December 2014
Location: Trento (IT)
Member
Thank you.
The problem is I am a C programmer and I know little of C++ Smile

The code above don't compile becouse of a missing declaration:


for(KeyValueRef pair : ~kv) {
out << Format("%s=%s\n", pair.key, pair.value);
}

In the first line:
error: use of class template 'KeyValueRef' requires template arguments.

??


Re: Ini file [message #58110 is a reply to message #58109] Wed, 16 February 2022 12:31 Go to previous messageGo to next message
jjacksonRIAB is currently offline  jjacksonRIAB
Messages: 219
Registered: June 2011
Experienced Member
KeyValueRef is already part of U++, it's contained in Core/Map.h. I posted the code to it for illustrative purposes but you don't want to recreate it in your program.

If Upp's KeyValueRef is not working it could be because you either haven't included Core/Core.h or you aren't using the Upp namespace.

#include <Core/Core.h>

using namespace Upp;

namespace Config {

INI_BOOL(flag1, false, "This is bool parameter 1")
INI_BOOL(flag2, true, "This is bool parameter 2")

INI_STRING(text, "default text", "Text parameter");

INI_INT(number, 123456, "Number parameter");
INI_INT64(size, 0, "Int64 parameter");

INI_DOUBLE(fp_number, 0.1, "Floating point parameter");

};

extern void ExternalFn();

CONSOLE_APP_MAIN
{
    StdLogSetup(LOG_COUT|LOG_FILE);
    
    SetIniFile(GetDataFile("test.ini"));
    
    RDUMP(Config::flag1);
    RDUMP(Config::flag2);
    RDUMP(Config::text);
    RDUMP(Config::number);
    RDUMP(Config::fp_number);
    
    RLOG(GetIniInfoFormatted());

    Config::number = 321;
    RDUMP(Config::number);
    
    RLOG(GetIniInfoFormatted());
    
    ExternalFn();

    // contains key value pairs for ini file
    VectorMap<String, String> kv = GetIniKeys();
    
    // add a new key
    kv.Add("testing", "new key");
    
    // replace an existing key's value
    kv.GetPut("text") = "non-default text";
    
    // remove an existing key
    kv.RemoveKey("number");
    
    FileOut out("test.ini");
    
    // write pairs to disk
    for(KeyValueRef pair : ~kv) {
        out << Format("%s=%s\n", pair.key, pair.value);
    }
}


If you wanted to instantiate KeyValueRef directly instead of receiving it as a return from a function, you'd do it like this:

String foo = "foo";
String bar = "bar";
KeyValueRef<String, String> test = { foo, bar };


You'll have to read up on template classes and template functions to understand how they work.
I'd also direct you to https://www.ultimatepp.org/src$Core$VectorMap_en-us.html
and https://www.ultimatepp.org/srcdoc$Core$Tutorial_en-us.html#C hapter_3 so you can learn about NTL containers.

Once you understand how containers in U++ work then you have the key to understanding many of the features of U++. A basic understanding of Vector and VectorMap along with templates are essential because they are such a common part of U++ functions and classes. Another thing I have discovered is critical to be able to find undocumented features is to just Ctrl+click on known features and look at the code adjacent to that and its headers for undocumented features. GetIniKeys() is not documented by an example program (and should be), but it is discoverable.

Incidentally I would have not named it GetIniKeys() because it's not returning just an array of keys, it's returning an array of keys and values. I would have named it GetIniPairs() but whatever Very Happy

[Updated on: Wed, 16 February 2022 13:06]

Report message to a moderator

Re: Ini file [message #58111 is a reply to message #58110] Wed, 16 February 2022 14:18 Go to previous messageGo to next message
Silvan is currently offline  Silvan
Messages: 56
Registered: December 2014
Location: Trento (IT)
Member
Thank you.
What it missed was: KeyValueRef<String, String>

Yes the documentation of U++ is big but don't cover everything and I use to navigate to the U++ source
to understand, but in this case I missed the solution.
Examples are the winning card.

Regards
Silvano

PS: 3. Array containers that is very important and vast and I need more time to practise Smile

[Updated on: Wed, 16 February 2022 14:20]

Report message to a moderator

Re: Ini file [message #58112 is a reply to message #58111] Wed, 16 February 2022 14:31 Go to previous messageGo to next message
jjacksonRIAB is currently offline  jjacksonRIAB
Messages: 219
Registered: June 2011
Experienced Member
Ahh yeah, I see what's going on. I'm using -std=c++2a for a later version of C++ which apparently doesn't require you to type in the template parameters. My bad for forgetting that not everyone is using later stuff.

If you don't want to have to do KeyValueRef<String, String> you can just use auto type deduction instead.

for(auto pair : ~kv) {
    out << Format("%s=%s\n", pair.key, pair.value);
}


Apparently that's been the case since C++17 and I just never stumbled on it. Technically in c++17 onward you can also do

VectorMap vm = GetIniKeys();


and it will auto-deduce the template parameters for you. Anyway: cheers!

[Updated on: Wed, 16 February 2022 14:52]

Report message to a moderator

Re: Ini file [message #58113 is a reply to message #58095] Thu, 17 February 2022 18:59 Go to previous messageGo to next message
Silvan is currently offline  Silvan
Messages: 56
Registered: December 2014
Location: Trento (IT)
Member
Still there is something I don't understand...

Your example works fine in console_app but not in a normal windows application.
The file ini will be written whitout nothing inside, and if I manually write it,
it will be overwritten empty.

After this, kv is empty:

SetIniFile(GetDataFile("test.ini"));
VectorMap<String, String> kv = GetIniKeys();
Re: Ini file [message #58114 is a reply to message #58113] Thu, 17 February 2022 21:57 Go to previous messageGo to next message
jjacksonRIAB is currently offline  jjacksonRIAB
Messages: 219
Registered: June 2011
Experienced Member
Just a guess, but when you switch compilers, switch from console app to windowed app and various other changes, it creates a new output directory for your build. Check and make sure the .ini file you're writing isn't being relocated along with it.
Re: Ini file [message #58117 is a reply to message #58095] Fri, 18 February 2022 18:50 Go to previous message
Silvan is currently offline  Silvan
Messages: 56
Registered: December 2014
Location: Trento (IT)
Member
Solved.... I have to add text.ini to the project.

Thx
Previous Topic: Synchronize to Github
Next Topic: ref questions
Goto Forum:
  


Current Time: Thu Mar 28 18:56:10 CET 2024

Total time taken to generate the page: 0.00853 seconds