0

I need to read parameters from a txt file for my program in Linux. But the result is that some of the parameters read from the txt file have the correct value, but some of them have a wrong value. Somebody has met this problem? I have translated the format of the txt in windows into Linux with the command dos2unix. I need your help, Thanks.

The read function is as follows:

template <class T>int ReadFileVar(ifstream *inClientFile, const char var_name[], T *var)
{
//inClientFile - pointer to the previously opened File stream
//var_name - contains the name of the variable
//var - pointer to a long, the function will return the value of the variable in this

int length_var_name = (int) strlen(var_name);
char line[512];
int i, j;

while (inClientFile->getline(line,512))
{
    if (line[0] != '/' && line[1] != '/')
    {
        i = 0;
        while (line[i] != '\0')
        {
            if (!strncmp(&line[i],var_name,length_var_name))
            {
                j = i + length_var_name;
                while (line[j] != '\0')
                {
                    if ( line[j] >= '0' && line[j] <= '9')
                    {
                        *var = (T) atof(&line[j]);
                        inClientFile->seekg( 0, ios_base::beg ); //back to the beginning of the file
                        return 0;
                    }
                    j++;
                }
            }
            i++;
        }
    }
}

cerr << var_name << " - cannot be found" << endl;
throw "error reading input data from: ";

return 1; //the specified variable was not found in the file
}

For example:

the parameters in the txt are as follows:,the type of them are long,

 nx=100;
 ny=100;
 nz=100;
 ipro=1;
 jpro=1;
 kpro=1;

but after reading the txt in my program I get these,

 nx=100;
 ny=100;
 nz=15;
 ipro=1;
 jpro=1;
 kpro=100;

I have tested the program under Windows, there it works!

10
  • why do you go back to the beginning of the file after each param? Commented Oct 16, 2013 at 13:49
  • why do you use atof if the type of parameters are long ? Commented Oct 16, 2013 at 13:51
  • ah I see you call that function for each parameter. seems like an awfully complicated way of reading the parameters, though. why not simply scan the file once line by line and store param name and value in a fitting structure, e.g. a map<string, long>? Commented Oct 16, 2013 at 13:51
  • I think the function has no error,because I had tested it in Windows,it works well.but in Linux,it has something wrong just like I say. I have many parameters in the txt file,they may be long,int,char and so on.@nyarlathotep @Michael Commented Oct 16, 2013 at 14:04
  • en.wikipedia.org/wiki/End_of_line Commented Oct 16, 2013 at 14:06

1 Answer 1

2

Your code works for me, you must have an error somewhere else or an undefined behavior I didn't spot.

May I suggest a more C++ way to do exactly the same thing :

template <class T>
T ReadFileVar(ifstream& inClientFile, string var_name)
{
    string line;
    while (getline(inClientFile, line))
    {
        if (line[0] != '/' && line[1] != '/')
        {
            size_t pos = line.find(var_name);
            if( pos != string::npos) {
                pos = line.find('=', pos + 1);
                if(pos == string::npos) {
                    throw std::exception();
                }
                istringstream iss(line.substr(pos + 1));
                T result;
                iss >> result;
                inClientFile.seekg( 0, ios_base::beg );
                return result;
            }
        }
    }
    throw std::exception();
}

You could also parse the whole file and store the result in a map instead of searching the whole file for each variable :

map<string, string> ParseFile(ifstream& inClientFile) {
    map<string, string> result;
    string line;
    while (getline(inClientFile, line))
    {
        if (line[0] != '/' && line[1] != '/')
        {
            size_t pos = line.find('=');
            if(pos == string::npos) {
                throw std::exception();
            }
            string var_name = line.substr(0, pos);
            string var_value = line.substr(pos + 1);
            result[var_name] = var_value;
        }
    }
    return result;
}

template <class T>
T ReadVar(map<string, string> data, string var_name)
{
    map<string, string>::iterator it = data.find(var_name);
    if(it == data.end()) {
        throw exception();
    }
    string value = it->second;
    istringstream iss(value);
    T result;
    iss >> result;
    return result;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.