Link to home
Start Free TrialLog in
Avatar of BeginToLearn
BeginToLearn

asked on

split string

hi all,
 my program is to  get value in a config file whose format is

[server1]
servername = ubuntu
port =50000
[server2]
servername = solaris
port = 37777

I use strrchr() to detect the index of '=' then  copy string and trim a possible of leading space of that string.

I think i have the problem with strrchr() because when it detect '=', it stops, so I need to move forward 1 index to exclude '=' from the string . I have tried, but fail. So please help me.
Also , is there are in better way to achieve same task with better code? tks.

PS: I just want to cover the case =50000 or = 50000, or =      50000 .
 
readconfig.c
Avatar of elimesika
elimesika
Flag of Israel image

Avatar of BeginToLearn
BeginToLearn

ASKER

how about my code? i don't want too complicated hihi
ASKER CERTIFIED SOLUTION
Avatar of Infinity08
Infinity08
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
In case you are doing that on Window - the file looks suspciously like the .ini file format for which MS has created APIs to read them, it could be as simple as
int nPort = GetPrivateProfileInt("Server2", "port", -1, "config.ini");

Open in new window


See

http://msdn.microsoft.com/en-us/library/ms724345%28VS.85%29.aspx ("GetPrivateProfileInt Function")
http://msdn.microsoft.com/en-us/library/ms724353%28v=VS.85%29.aspx ("GetPrivateProfileString Function")
oh jrk, it is not for windows. Its in ubuntu. tks.
do u mean like this in attachment?
readconfig.c
You're not just erasing spaces at the beginning and end, and you're also not taking care of other types of whitespace (like tabs eg.). But that's a good start, yes.
oh Infinity08,
 you mean besides space ' ', i need to consider tab also?
>>  you mean besides space ' ', i need to consider tab also?

Whitespace includes spaces, tabs, vertical tabs, newlines, carriage returns.
If you want to account for all cases, then you should remove all these types of whitespace from the beginning and end of the key and value.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
The // Eat leading whitespace comment and the one following the next return are a kind of misleading.  Basically, the i is set to the beginning of the next token, j is set to the following delimiter, and the token is extracted to the container.  More consecutive delimiters is treated as one (here called whitespaces, but in the code they are the charecters from the delimiter argument).  

The usage in your case would be like:

    string s("servername = ubuntu");
    ...
    vector<string>  vec;
    stringtok (vec, s, " =");  // both space and '=' as delimiters

Open in new window


Then you can check the size of the vector and get the vec[0] as the "servername" and vec[1] as "ubuntu".  The same template can be used to build a list<string> and set<string>.

However, there is a problem with spaces/'=' inside the value.  You may want to enhance the template by say maxsplit argument to be able to prescribe you wan to split the string say max once.  

However, it is probably better to write your own function that splits the string on the first '=', and returns the pair<string, string> with the name and value.
Looking at your code, you should consider to convert it from C/C++ (i.e. from mixture of both) to pure C++.   You may not like this idea, but it is better to do it sooner than later.

I can see your example to be the ideal one to present looping through the text file, using the finite automaton for parsing of the .ini like files (with sections), using the streams instead of working with buffers and with printf(), etc.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
tks a lot for all suggestion. I am reading all now. By the way, please take a look at other questions and https://www.experts-exchange.com/questions/26946319/apache.html

Honestly I want to move to C++ , but sometimes I don't have enough knowledge/skill to move on. That's why you can see i am in the middle of C and C++. ( So i use the orginal version of readConfig as a backup version)

I understand the comments from pepr now. I decide to to combine it with Sara's suggestion to use map because of "where you later could easily look-up for sections (like [server1]) and single keys within a section.
"

Let me work on it now.
i have finished the main frame of new readconfig. the only part left is the insert into the map in if ( flag == 3).
I think for insertion to the map, I only use the second element on   vector v1 and v2 to the map?
Am I on the right track?
readconfig.c
i just finished it. I think it is ok. However, i still need  your advise to make sure it usable later on. tks.
readconfig.c
There's no reason to use C style I/O or C style string operations. You chose to do this in C++, and to use std::string, so it's better to do that consistently.

Start by renaming your file to .cpp, then replace the C style I/O with C++ style I/O :

        http://www.cplusplus.com/doc/tutorial/files/

And use the std::string functionality :

        http://www.cplusplus.com/reference/string/
Thinking in C++ by Bruce Eckel can be bought in paper form but also downloaded in HTML for free -- also excellent book (http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html).  Of course, you should start it from beginning.  The shortcuts to strings and iostream are -- assuming you extract the books to the ThinkinInCpp directory:

3: Strings in Depth -- ThinkingInCpp/Volume2/TicV2.html#_Toc53985657
4: Iostreams -- ThinkingInCpp/Volume2/TicV2.html#_Toc53985673
Today i checked out Absolute C++ and C++ cookbook . they help me on how to display the map of map :)
You can simply display them using the reverse way that you used when building it.  You can generate the file similar to the one that has been consumed for the input -- i.e. section (keys of the first-level map) with lines id=value where id is the key of the second-level map.

The process is basically two nested loops.  The first loop prints the section and enters the second loop.  The second loop produces pairs (key, value) and you can print them separated by '='.

The only problem is to know how to iterate through all the keys of the map.