Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
245 views
in Technique[技术] by (71.8m points)

Why can't I perform a comparison when iterating over a vector in C++?

I'm trying to look at each element of a vector to see if it is equal to the specified string.

The code looks like this:

for (int i = 0; i < menuVector.size(); i++) {
  if (menuVector[i] == "a") {
    type = "Appetisers";
    name = menuVector[i + 1];
    price = std::stod(menuVector[i + 2]);
    calories = std::stoi(menuVector[i + 3]);

    if (menuVector[i + 4] == "y") {
      shareable = true;
    } else {
      shareable = false;
    }

    if (menuVector[i + 5] == "y") {
      twoForOne = true;
    } else {
      twoForOne = false;
    }

    createMenu(shareable, twoForOne, name, price, calories, type, millilitres, abv);
  }
                
  if (menuVector[i] == "m") {
    type = "Main dishes";
    name = menuVector[i + 1];
    price = std::stod(menuVector[i + 2]);
    calories = std::stoi(menuVector[i + 3]);
    createMenu(shareable, twoForOne, name, price, calories, type, millilitres, abv);
  }

  if (menuVector[i] == "b") {
    type = "Beverages";
    name = menuVector[i + 1];
    price = std::stod(menuVector[i + 2]);
    calories = std::stoi(menuVector[i + 3]);
    millilitres = std::stoi(menuVector[i + 6]);
    abv = std::stod(menuVector[i + 7]);

    createMenu(shareable, twoForOne, name, price, calories, type, millilitres, abv);
  }
}

The first comparison against "a" works once. However, it fails to work again for the additional instances of "a". All the other comparisons against "m" and "b" don't work. Despite the fact that if I write 'std::cout << menuVector[42];` it gives me "m".'

Using the same for loop to print out every element in the array gives me this output:

aNachos4.99600yn
aBuffalo wings3.99450ny
aGarlic bread3.99500ny
mBurger9.99950
mMac & cheese7.99850
mFish & chips8.991000
mChicken tikka masala6.99700
bLager3.52005684.5
bWhite wine415017511.5
bRed wine417017512.5
bCoke2.51403300
bWater1.503300

The function that displays the menu looks like this:

std::string Menu::createMenu(bool shareable, bool twoForOne, std::string name, double price, int calories, std::string type,int millilitres,double abv) {
  std::cout << "--------------------" << type << "-----------------------" << std::endl;
  std::cout << name << ": x9C"; 
  std::printf("%.2f", (price));
  std::cout << ", " << std::to_string(calories) << " cal, ";

  if (type == "Beverages") {
    std::cout << "(" << millilitres << ", " << abv << " abv)";
  }

  if (shareable) {
    std::cout << "(shareable)" << std::endl;
  } else if(twoForOne) {
    std::cout << "(2-4-1)" << std::endl;
  }

  return name;
}

The current output is this:

--------------------Appetisers-----------------------
Nachos: £4.99, 600 cal, (shareable)

Why is only one appetiser being outputted? Surely it should enter each if statement when menuVector[i] equals that string.

Here is a Minimal, Reproducible Example:

Menu.h File:

#pragma once
#include <iostream>
#include <string>
#include <fstream>
#include <algorithm>
#include <vector>
#include <sstream>
#include <cmath>
#include <iomanip>

class Menu 
{
private:
    std::vector<std::string> menuVector;
public:
    Menu(std::string menuDirectory);
    std::string createMenu(bool shareable, bool twoForOne, std::string name, double price, int calories, std::string type, int millilitres, double abv);


    

};

Menu.cpp File:

#include "Menu.h"
Menu::Menu(std::string menuDirectory) {

    std::ifstream menuFile;

    bool shareable{ false };
    bool twoForOne{ false };
    std::string name{ " " };
    double price{ 0 };
    int calories{ 0 };
    std::string type{ " " };
    int millilitres{ 0 };
    double abv{ 0 };


    while (true) {

        try {
            menuFile.open(menuDirectory);
            std::string line;


            std::vector<std::string> menuVector;

            while (std::getline(menuFile, line, ',')) {


                menuVector.push_back(line);

            }



            for (int i = 0; i < menuVector.size(); i++) {




                if (menuVector[i] == "a") {


                    type = "Appetisers";

                    name = menuVector[i + 1];
                    price = std::stod(menuVector[i + 2]);
                    calories = std::stoi(menuVector[i + 3]);
                    if (menuVector[i + 4] == "y") {
                        shareable = true;
                    }
                    else {
                        shareable = false;
                    }

                    if (menuVector[i + 5] == "y") {
                        twoForOne = true;
                    }
                    else {
                        twoForOne = false;
                    }

                    createMenu(shareable, twoForOne, name, price, calories, type, millilitres, abv);

                }


                if (menuVector[i] == "m") {
                    type = "Main dishes";

                    name = menuVector[i + 1];
                    price = std::stod(menuVector[i + 2]);
                    calories = std::stoi(menuVector[i + 3]);
                    createMenu(shareable, twoForOne, name, price, calories, type, millilitres, abv);
                }


                if (menuVector[i] == "b") {
                    type = "Beverages";
                    name = menuVector[i + 1];
                    price = std::stod(menuVector[i + 2]);
                    calories = std::stoi(menuVector[i + 3]);
                    millilitres = std::stoi(menuVector[i + 6]);
                    abv = std::stod(menuVector[i + 7]);

                    createMenu(shareable, twoForOne, name, price, calories, type, millilitres, abv);

                }


            }




            


        }
        catch (const std::ifstream::failure& e) {
            std::cout << "An error occured reading the menu.csv file" << std::endl;
        }

        break;

    }


    menuFile.close();

}

std::string Menu::createMenu(bool shareable, bool twoForOne, std::string name, double price, int calories, std::string type, int millilitres, double abv) {


    std::cout << "--------------------" << type << "-----------------------" << std::endl;
    std::cout << name << ": x9C";
    std::printf("%.2f", (price));
    std::cout << ", "
        << std::to_string(calories) << " cal, ";

    if (type == "Beverages") {
        std::cout << "(" << millilitres << ", "
            << abv << " abv)";
    }

    if (shareable) { std::cout << "(shareable)" << std::endl; }
    else if (twoForOne) {
        std::cout << "(2-4-1)" << std::endl;
    }

    return name;
}

Main.cpp File:

#include "Menu.h"


int main()
{
    Menu menu = Menu("menu.csv");
}

CSV file data that's read into the vector

a,Nachos,4.99,600,y,n,,
a,Buffalo wings,3.99,450,n,y,,
a,Garlic bread,3.99,500,n,y,,
m,Burger,9.99,950,,,,
m,Mac & cheese,7.99,850,,,,
m,Fish & chips,8.99,1000,,,,
m,Chicken tikka masala,6.99,700,,,,
b,Lager,3.5,200,,,568,4.5
b,White wine,4,150,,,175,11.5
b,Red wine,4,170,,,175,12.5
b,Coke,2.5,140,,,330,0
b,Water,1.5,0,,,330,0


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

There is a problem in your csv reading. By splitting on the , character the gets appended on the next token, e.g. the next a in your csv it's a a.

Take this as an example

#include <string>
#include <iostream>
#include <sstream>

int main() {
    std::stringstream in;
    in << "1,2,3
4,5,6
7,8,9
";
    std::string line;
    while (std::getline(in, line, ','))
        std::cout << line;
}

The output is

123
456
789

You should split by row and then by token

#include <string>
#include <iostream>
#include <sstream>

int main() {
    std::stringstream in;
    in << "1,2,3
4,5,6
7,8,9
";
    std::string line, token;
    while (std::getline(in, line, '
')) {
        std::stringstream liness;
        liness << line;
        while (std::getline(liness, token, ','))
            std::cout << token;
    }
}

The output is

123456789

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...