vzste
vzste

Reputation: 139

Attempt to convert string variable to bool results in "true" & "false" both equal to 0

I'm new to C++ and I am probably missing something minor but have been staring at this for way too long and would really appreciate some help.

I'm working on an assignment where the program reads in data from a CSV file. To start, I'm importing all the data in as strings using getline() because that's the only way I know how. Once imported, I want (am trying) to convert the string variables taking on "TRUE" and "FALSE" to bool types.

The CSV file contains:

name,color,age,wild,home,endagered
Foo,brown,3,TRUE,Malaysia,FALSE

Below is my code. I realize this is probably very inefficient, but I'm learning, so... it is what it is.

Here is the conversion function (it's supposed to be able to handle errors in the file):

void stringBool(const string & temp, bool newVar)
{
    const string fc = "FALSE";
    const string fl = "false";
    const string tc = "TRUE";
    const string tl = "true";

    try {
        if (temp==fc || temp==fl)
        {
            newVar = false;
        }
        else if (temp==tc || temp==tl)
        {
            newVar = true;
        }
        else
        {
            throw temp;
        }
    } catch (string e) {
        cout << newVar << " = " << e << " is not in the correct format. Check your file and try again." << endl;
        exit(1);
    }
};

And here is the read-in member function for a class. It is a virtual function in a derived class if that matters. (Didn't want inundate the post with less relevant code, but please let me know if you want to see it.)

void readIn(std::string filename)
    {
        ifstream myFileStream(filename);

        //Error if file fails to open
        if(!myFileStream.is_open())
        {
            cout << "File failed to open" << endl;
            exit(1);
        }

        //Temporary strings to import
        string ag, wld, endg;
        string myString, line;

        //Read in data
        getline(myFileStream, line); //Skip first line
        while(getline(myFileStream, line))
        {
            stringstream ss(line);
            getline(ss, name, ',');
            getline(ss, color, ',');
            getline(ss, ag, ',');
            getline(ss, wld, ',');
            getline(ss, home, ',');
            getline(ss, endg, ',');
        }
        myFileStream.close();

        //Convert variables from string to appropriate form
        stringBool(wld, wild);
        stringBool(endg, endanger);
        age = stoi(ag);

        //Print variables to check
    cout <<  name << endl << color << endl << age << endl << wild << endl << home << endl << endanger << endl;

    //Print temporary variables
    cout << wld << endl;
    cout << endg << endl;
    };

And when I actually call on the function in main, the output is:

Foo
brown
3
0
Malaysia
0
TRUE
FALSE

So even though the data have imported correctly (the strings are correct - wld=TRUE and endg=FALSE), both wild and endanger are 0.

I would be really grateful for any help. Thanks.

Upvotes: 1

Views: 194

Answers (2)

therealsib
therealsib

Reputation: 11

Firstly if you're "using namespace std" that is generally considered a bad practise. Secondly if you want to change a passed in variable to a function pass that variable in as a reference. Like this:

bool& newVar

Upvotes: 1

Alecto
Alecto

Reputation: 10740

Here:

void stringBool(const string & temp, bool newVar)
{

You're passing newVar by value. If you want changes to newVar to change the value in the corresponding function, it should be a reference:

void stringBool(const string & temp, bool& newVar)
{

Alternatively, just have it return the value:

bool stringBool(const std::string& temp) {
    if(temp == "true" || temp == "TRUE") return true;
    if(temp == "false" || temp == "FALSE") return false;
    throw std::invalid_argument("Input '" + temp + "' should be either 'true' or 'false'");
} 

You can find std::invalid_argument by including <stdexcept>

Upvotes: 4

Related Questions