How to compare 2 std::strings in an if statement

I'm trying to compare 2 std::string variables in order to determine if my program is running on a Raspbian Linux distro.

The function runs a bash script that returns the results of "cat /etc/os-release | grep ID". After that it splits the results into different words, so I can isolate the word "raspbian" after the word "ID=". Similar to the split function in JavaScript.

Executing the bash script and splitting the results work perfectly. The problem is that my if statement is not picking up the comparison even though the name "raspbian" comes up as expected.

I created the std::string rasp variable just in case the if statement is not working due to the difference in data types, but nothing. I'm definitely doing something wrong.

Hope this makes sense :(

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bool Utils::CheckIfRaspberry() {
    bool isRPi = false;
    std::string rasp = "raspbian";

    std::string res = Exec("cat /etc/os-release | grep ID");
    std::vector<std::string> splitArray;
    splitArray = Split(res, "=");
    for (unsigned int i = 0; i < splitArray.size(); i += 1) {
        if (splitArray[i] == rasp) {
            std::cout << "A Raspberry!" << "\n";
            isRPi = true;
        }
    }
    return isRPi;
}
Last edited on
Hi,
splitArray = Split(res, "=");

Can you let us see your Split() function?
Absolutely!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
std::vector<std::string> Utils::Split(const std::string &str, const std::string &key) {
    std::vector<std::string> tokens;
    size_t prev = 0, pos = 0;
    do {
        pos = str.find(key, prev);
        if (pos == std::string::npos) { pos = str.length(); }
        std::string token = str.substr(prev, pos-prev);
        if (!token.empty()) {tokens.push_back(token); }
        prev = pos + key.length();
    }
    while (pos < str.length() && prev < str.length());
    return tokens;
}



...and just in case, this is the Exec function that runs the Bash Script:

1
2
3
4
5
6
7
8
9
10
11
12
13
std::string Utils::Exec(const char *cmd) {
    std::string result = "";
    FILE *pipe = popen(cmd, "r");
    if (!pipe) {return "ERROR";}
    char buffer[128];
    while(!feof(pipe)) {
        if(fgets(buffer, 128, pipe) != NULL) {
            result += buffer;
        }
    }
    pclose(pipe);
    return result;
}
Last edited on
You can simplify the script by making it grep ID /etc/os-release.
I suspect that what's coming back is "ID=raspbian\n" rather than "ID=raspbian"
Last edited on
Would the "\n" be visible if I print out the vector items? I did print them out and unfortunately don't see the "\n". In fact this is what I see:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    for (unsigned int i = 0; i < splitArray.size(); i += 1) {

        // Print out Vector Items
        std::cout << "Tokens: " << splitArray[i] << "\n";

        if (splitArray[i] == rasp) {
            std::cout << "A Rapsberry: " << splitArray[i] << "\n";
            isRPi = true;
        }
    }

// Console
Tokens: VERSION_ID
Tokens: "8"
ID
Tokens: raspbian // Not detecting this item :(
ID_LIKE
Tokens: debian
Last edited on
Actually, dhayden was on the spot with his answer, it does have to do with a \n.

If I change the rasp variable to let's say "VERSION_ID". It finally works. Why? That token in particular is actually alone, with no new lines.

If you notice the raspbian token on the other hand, it's also including "ID_LIKE". That's the problem. I need to find a better way to isolate particular words in strings. So yeah, that's what's going on.

Thanks, finally on the right track.
Topic archived. No new replies allowed.