954,506 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Variable pointers or References for .conf parser?

hello I am new to C++. I understand pointers and references a little and I must be missing something in conf.cpp. Would you help by pointing out my errors for my pointers coding errors related to my problem? Main reason I am asking is because I get a segment fault where 'servername' is.

system header and conf.h's relative include:

#include <iostream>
#include <fstream>
#include <string>
using namespace std;


the example varible and an shortcut I picked up the source conf.h:

#define E extern
E string &servername;


termed source of conf.cpp for veiwing purposes:

string &servername;

//parse line
int cur;
int dirint;
int smspace = 1;

void parse(string line) {
    string sub;
    string pram;
    string subval;
    int len = line.length();
    
    for (int i = 0; i < len; i++)
    {
        if (line[i] == '\t') {
        } else if (line[i] == '"') {
            if (line[i + 1] == ';') {
                cout << "|\";|"<< endl;
                smspace = 1;
                cur = 0;
            } else {
                
                cur = 1;
                cout << "|\"|";
                smspace = 0;
            }
        }else if(smspace == 1 && line[i] == ' ') {
        } else {
            
            if (sub == "servername"){
                if (cur == 0)
                servername = "test";
                cout << &servername;
            }
            if (cur == 1) {
                pram += line[i];
            } else {
                sub += line[i];
            }
        }
        
    }
}
void read_conf() {
    ifstream in ( CONF_FILE );
    
    if ( in.is_open() ) 
    {
        string line;
        int ret = 0;
        int linenum = 0;
        while ( getline ( in, line ) ) {
            string::size_type i = line.find_first_not_of ( " \t\n\v" );
            linenum++;
            if ( i != string::npos && line[i] == '#' )
            {
                continue;
            }
            if (ret == 1)
            {
                if ( i != string::npos && line[i] == '*' )
                {
                int ptr = i + 1;
                if ( i != string::npos && line[ptr] == '/' )
                {
                    ret = 0;
                }
                continue;
            }
            }
        if ( i != string::npos && line[i] == '/' )
                {
                    int ptr = i + 1;
                    if ( i != string::npos && line[ptr] == '*' )
                    {
                        ret = 1;
                        continue;
                    }
        };
        parse(line);
        }
        
    };
};
mknight
Newbie Poster
6 posts since Nov 2006
Reputation Points: 10
Solved Threads: 0
 

Firstly what does your input file look like? Post an example.

Second give an exact description of what you expect your program to do.

iamthwee
Posting Expert
5,950 posts since Aug 2005
Reputation Points: 1,543
Solved Threads: 439
 

sorry! I just realized I forgot the most important detail the .conf file:

/*  general server configurations  */

#################
#Server Settings#
#################
servername "NightServ.NightIRC.org";
description "NightIRC service an rare constellation of stars";
myaddress "127.0.0.1";
port "8087";
mknight
Newbie Poster
6 posts since Nov 2006
Reputation Points: 10
Solved Threads: 0
 

sorry! I just realized I forgot the most important detail the .conf file:

/*  general server configurations  */

#################
#Server Settings#
#################
servername "NightServ.NightIRC.org";
description "NightIRC service an rare constellation of stars";
myaddress "127.0.0.1";
port "8087";


Ok I assume that's your input file. Can you give a brief description of what your program will do.

iamthwee
Posting Expert
5,950 posts since Aug 2005
Reputation Points: 1,543
Solved Threads: 439
 

Most certainly! My program is going to be an IRC Services server. At this stage of engineering I am as you see working on the configurations file routings. getting the pram variable data into the an variable that will be accessible through out the program is my problem. As for the main.cpp it is only calling the read_conf(); in conf.cpp.

mknight
Newbie Poster
6 posts since Nov 2006
Reputation Points: 10
Solved Threads: 0
 
Most certainly! My program is going to be an IRC Services server. At this stage of engineering I am as you see working on the configurations file routings. getting the pram variable data into the an variable that will be accessible through out the program. As for the main.cpp it is only calling the read_conf(); in conf.cpp.



Ok that was a rather generic explantion. I was looking for something more detailed. Such as:

My input file looks like this:server.txt

/*  general server configurations  */

#################
#Server Settings#
#################
servername "NightServ.NightIRC.org";
description "NightIRC service an rare constellation of stars";
myaddress "127.0.0.1";
port "8087";


I want my program to go through the file and store information from the file into string variables.

i.e

string servername = "NightServ.NightIRC.org";

That would help me help you better now wouldn't it?

iamthwee
Posting Expert
5,950 posts since Aug 2005
Reputation Points: 1,543
Solved Threads: 439
 

Yes, I am sorry. I'll do better next time, now I got an idea of how to form my posts. As for the description you gave was right on the nose.

mknight
Newbie Poster
6 posts since Nov 2006
Reputation Points: 10
Solved Threads: 0
 

Ok I think I understand this better now

Here is the most important information:

servername "NightServ.NightIRC.org";
description "NightIRC service an rare constellation of stars";
myaddress "127.0.0.1";
port "8087";


Yep, so first we need to split the .txt file into lines.

Storing each line as a string.


Next we need to establish what thefirst word is of each line is. Then we can match this word with our string variables.

i.e.

string sub;      = servername
    string pram;    = description
    string subval;  = myaddress
    port???


Finally once we have identified which line contains which variable we just need to extract the information between the quotes. And then store that into the corresponding variable.

Is this right so far?

iamthwee
Posting Expert
5,950 posts since Aug 2005
Reputation Points: 1,543
Solved Threads: 439
 

Ok I think I understand this better now

Here is the most important information:

servername "NightServ.NightIRC.org";
description "NightIRC service an rare constellation of stars";
myaddress "127.0.0.1";
port "8087";

Yep, so first we need to split the .txt file into lines.

Storing each line as a string.

Next we need to establish what thefirst word is of each line is. Then we can match this word with our string variables.

i.e.

string sub;      = servername
    string pram;    = description
    string subval;  = myaddress
    port???

Finally once we have identified which line contains which variable we just need to extract the information between the quotes. And then store that into the corresponding variable.

Is this right so far?

I am so sorry again! I didn't remove the unused variables like the subval, dirint.

you got the idea of what I am trying todo just that the sub is the directive word and pram is the value. As shown

string sub = servername
string pram = NightServ.NightIRC.org



The code would cycle through the lines and test the word then assign the matching value to the matching variable:

void parse(string line) {
    string sub;
    string pram;
    int len = line.length();
    
    for (int i = 0; i < len; i++)
    {
        if (line[i] == '\t') {
        } else if (line[i] == '"') {
            if (line[i + 1] == ';') {
                cout << "|\";|"<< endl;
                smspace = 1;
                cur = 0;
            } else {
                
                cur = 1;
                cout << "|\"|";
                smspace = 0;
            }
        }else if(smspace == 1 && line[i] == ' ') {
        } else {
            
            if (sub == "servername"){
                if (cur == 0)
                servername = "test";
                cout << &servername;
            }
            if (cur == 1) {
                pram += line[i];
            } else {
                sub += line[i];
            }
        }
        
    }
}

To explain the code better the 'read_conf()' loads a line into the line test to see if it should ingore the comment lines then send it to parse to evaluate the line further. if the program will also ingore tabs. As for spaces it uses an logic controls to allow or disallow spaces smspace is set to 1 so it will ingore spaces by default. As for 'cur' variable which stands for cursor to which variable it would be either 'sub' or 'pram' variables.

if (cur == 1) {
                pram += line[i];
            } else {
                sub += line[i];
}

After that it would compare the first word to the corsponding if control to find out what variable is going to host the 'pram' values. this as I said is the part I am having problems with.

mknight
Newbie Poster
6 posts since Nov 2006
Reputation Points: 10
Solved Threads: 0
 

Normally I don't do this but I don't have time to explain.

#include <fstream>
#include <iostream>
#include <string>

using namespace std;

string quoteExtract( string );
string extractFirstWord( string );

int main()
{
  string line;

  
  ifstream open ( "c:\\yourfile.txt" );
  
  while (getline(open,line,'\n')) //read in each line from the file
  {
        
    if (extractFirstWord(line)== "servername")
    {
       cout << quoteExtract (line);
    }
    
                                             
  } 
  open.close(); //close file
  cin.get(); //pause program
}

/*
 * Input: std::string
 * Returns: std::string
 * Purpose: To extract the characters between only ONE pair of quotes
 */
string quoteExtract (string line)
{
    
    int start,len; //Declare variables
    
    //string line = "description \"NightIRC service an rare constellation of stars\";";
    
    start =  line.find_first_of( "\"" ); //stores position of first quote
    len   =  line.rfind( "\"" );  //stores position of last quote
    
    //cout << "Found first quote at:";
    //cout << start;
    //cout << "\nFound second quote at:";
    //cout << len << "\n";
    
    string extract;
    extract =  line.substr( start + 1, ( len -( start + 1 ) ) ); 
    //extracts the characters between quotes
    return extract;
    
    //cin.get();
}

/* Extracts the first word in a file
 * Assumes no preceding whitespace before the
 * first word
 */
string extractFirstWord( string line )
{
   int start;
   start =  line.find_first_of( " " ); //stores position of first space
   string extract;
   extract =  line.substr( 0, start ); //extracts the first word
   
   return extract;
}


It might not do exactly as you want but it should give a starting point.

iamthwee
Posting Expert
5,950 posts since Aug 2005
Reputation Points: 1,543
Solved Threads: 439
 

Thank you for taking your time. from looking at your source I am quite intreged by treating variable as a function. I never thought you can do that. Well I'll give you a some of credit for your help in the realise of my open source IRC services server that I am writing. Though this is not what I am looking for but it will most likely help someone else out because there is only one really good example of how to parse an configuration file. The first example is at http://www.daniweb.com/techtalkforums/thread33579.html for those that are have simular problem as me

mknight
Newbie Poster
6 posts since Nov 2006
Reputation Points: 10
Solved Threads: 0
 

Fair enough.

I have no idea how a .conf file is meant to be parsed, but if you found a solution good for you. If you get stuck on any other string parsing you can always ask here.

iamthwee
Posting Expert
5,950 posts since Aug 2005
Reputation Points: 1,543
Solved Threads: 439
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You