I just can't help but feel that there's a more efficient way to do this than with multiple calls to the string[i] operator.

I've tried storing the results of string[i], but that leaves me with a char, which I'm evidently unable to compare. I know that I can compare a char*, but from what I can tell, that's a C char and string[i] provides me with a C++ char.

I could be way off with my entire analysis of the situation, so any help would be greatly appreciated.

void proc_cnf_line(Settings& settings, string line)
{
    string param_name;
    string param_value;
    bool param_named = false; //for deciding which string characters are placed into as encountered
    bool param_val_encountered = false; //for getting rid of leading spaces in param values
    for (strsize ss = 0; ss < line.size(); ss++)
    {
        if (param_named == false)
            {
                if (line.compare(ss, 1, "=") == 0)
                    param_named = true;
                else
                {
                    if (line.compare(ss, 1, " ") != 0)
                        param_name += line[ss];
                }
            }
        else
        {
            if (line.compare(ss, 1, " ") != 0)
            {
                if param_val_encountered == false
                    param_val_encountered = true;
                param_value += line[ss];
            }

        }

    }
}

Edited 4 Years Ago by oscargrower11

If you're going for efficiency, make line constant and get rid of the calls to "compare". You're comparing one character strictly for equality, so just compare the characters...

if(line[ss] == '=') // or any of the other comparisons

The overhead of [] is negligible. There's some quick math to get an address. I wouldn't worry about it much.

As to your code itself, looks like you're splitting the string into two strings using = as the delimiter and tossing the spaces. Lines 23 and 24 can be replaced with

param_value_encountered = true;

The variable seems to do you no good at all and can be deleted. I don't see any effect it could have on the code. I think I see what you're TRYING to do with the variable, but you have a boolean variable and you adjust its value and do nothing anywhere with the value. Presumably it needs to be part o an if statement somewhere.

In line 7, you might want to get rid of the call to

line.size()

in the loop condition. Make "line" constant and assign a constant to equal line.size()

The compiler might optimize all that. I'm not real clear on how strings are stored internally. It might not cause as many problems as repeated calls to strlen with C strings. Still, since you're talking efficiency. Avoid all those needless calls to

size()

As to your code itself, looks like you're splitting the string into two strings using = as the delimiter and tossing the spaces.

It is possible that a "=" could be held within the second string, though, since it will sometimes contain file paths and I'm going for 'nix compatability.

You're right though:

if (param_value_encountered == true)
    param_value += line[ss]
else
{
    if (line.compare(ss, 1, " ") != 0)
    {
        if (param_val_encountered == false)
            param_val_encountered = true;
        param_value += line[ss];
    }
}

is what I'm going for. In retrospect, though, getting rid of leading spaces would also be counterproductive in terms of 'nix comaptability without a separate subroutine to see if the leading spaces were intentional or not.

if(line[ss] == '=') // or any of the other comparisons

I was not actually aware that I could do this. I knew it worked in python, but for whatever odd reason, I seem to recall it failing spectacularly in mingw.

There's some quick math to get an address. I wouldn't worry about it much.

Any real reason not to though?

edit:

if (line[ss] == "=") == 0)

Mingw definitely barfs here with "ISO C++ forbids comparison between pointer and integer"

Edited 4 Years Ago by oscargrower11

if (line[ss] == "=") == 0)

Mingw definitely barfs here with "ISO C++ forbids comparison between pointer and integer"

update:
Here's what I'm looking at now; it's compiling, running and doing what it's supposed to.

void proc_cnf_line(Settings& settings, const string line)
{
    string param_name;
    string param_value;
    bool param_named = false; //for deciding which string characters are placed into as encountered
    bool param_val_encountered = false; //for getting rid of leading spaces in param values
    const strsize line_size = line.size();
    for (strsize ss = 0; ss < line_size; ss++)
    {
        if (param_named == false)
            {
                if (line.compare(ss, 1, "=") == 0)
                    param_named = true;
                else
                {
                    if (line.compare(ss, 1, " ") != 0)
                        param_name += line[ss];
                }
            }
        else
        {
            if (param_val_encountered == true)
                param_value += line[ss];
            else
            {
                if (line.compare(ss, 1, " ") != 0)
                {
                    if (param_val_encountered == false)
                        param_val_encountered = true;
                    param_value += line[ss];
                }
            }
        }

    }
}

I can't do a simple comparison of

if (line[ss] == "=")

since one of them results in an integer (I forget which, but recall running into either "H" or "K" repeatedly spitting out "104" when I was previously trying to run tolower() through cout) and the other a pointer. I'm thinking I might benefit from a character type primer, and I will look for one, but I'd be grateful to anyone who could takiea few paragraphs to spell out the ABCs for me until I find it. I know there is a more efficient way of doing this.

Edited 3 Years Ago by Dani: Fixed formatting

See my post again. SINGLE, not double quotes. You're comparing a character to a character. Nothing to do with Linux or mingw. What you had would "barf" no matter what compiler.

    if(line[ss] == '=')

See also the earlier point(partially) regarding lines 28 and 29. No need for the "if", then assigning it to true if it was false. Just assign it to true.

See my post again. SINGLE, not double quotes. You're comparing a character to a character. Nothing to do with Linux or mingw. What you had would "barf" no matter what compiler.

Dammit, sorry. Not the first time I've run across this. Python spoiled me in this regard.

See also the earlier point(partially) regarding lines 28 and 29. No need for the "if", then assigning it to true if it was false. Just assign it to true.

With you. Thanks a lot.

As to the other points, as far as the [] operator goes and the amount of time that takes, I imagine it gets fairly technical if you really want to optimize. My guess is that it might be better to make "line" a const char*. Line 8 would become this

while(line != 0)

Everywhere you see line[ss] replace it with *line

At the bottom of the loop, just stick this in: line++;

That's probably more efficient all around. Who knows, though. Certainly if you keep line as a string, you'll want to have it as const string& line for more efficient code.

I imagine only trial and error will get it to its ultimate efficiency. and the compiler does all sorts of optimizations on its own. You have to think of the time and resources it takes to do an allocation and deep copy in order to use a char* versus the amount of time it saves to figure out how long the string is and use the []. You also have to decide how much you care. If these are short strings, this is a fast function regardless.

You also have to decide how much you care.

If I didn't care, I'd have stuck to python,

If these are short strings, this is a fast function regardless.

More than a handful over 256 characters, more than a few over 1024. Granted, it's largely academic at this point in time, but I fully intend to produce FOSS code for a niche that is sorely lacking in FOSS code.

This article has been dead for over six months. Start a new discussion instead.