Попытка преобразовать строковую переменную в bool приводит к тому, что «true» и «false» оба равны 0 - PullRequest
1 голос
/ 19 апреля 2019

Я новичок в C ++ и, возможно, мне не хватает чего-то незначительного, но я слишком долго смотрел на это и был бы очень признателен за помощь.

Я работаю над заданием, в котором программа считывает данные из файла CSV. Для начала я импортирую все данные в виде строк, используя getline (), потому что это единственный способ, которым я знаю, как это сделать. После импорта я хочу (пытаюсь) преобразовать строковые переменные, принимающие значения «ИСТИНА» и «ЛОЖЬ», в типы bool.

Файл CSV содержит:

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

Ниже мой код. Я понимаю, что это, вероятно, очень неэффективно, но я учусь, так что ... это то, что есть.

Вот функция преобразования (она должна обрабатывать ошибки в файле):

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);
    }
};

А вот читаемая функция-член для класса. Это виртуальная функция в производном классе, если это имеет значение. (Не хочу заполнять пост менее значимым кодом, но, пожалуйста, дайте мне знать, если хотите его увидеть.)

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;
    };

И когда я на самом деле вызываю функцию в main, вывод:

Foo
brown
3
0
Malaysia
0
TRUE
FALSE

Таким образом, даже если данные были импортированы правильно (правильные строки - wld=TRUE и endg=FALSE), оба значения wild и endanger равны 0.

Буду очень признателен за любую помощь. Спасибо.

Ответы [ 2 ]

4 голосов
/ 19 апреля 2019

Здесь:

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

Вы передаете newVar по значению. Если вы хотите изменить значение newVar, чтобы изменить значение в соответствующей функции, это должна быть ссылка:

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

В качестве альтернативы, просто верните значение:

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'");
} 

Вы можете найти std::invalid_argument, включив <stdexcept>

1 голос
/ 19 апреля 2019

Во-первых, если вы «используете пространство имен std», это обычно считается плохой практикой.Во-вторых, если вы хотите изменить переданную переменную на функцию, передайте эту переменную в качестве ссылки.Как это:

bool& newVar
...