0

I've been scouring the forums and internet trying to find a solution to my problem but I can't seem to find anything that relates to me specifically. As a disclaimer, while this relates to homework, the question I'm asking isn't how to do it, it's how to fix a problem in what I already have done.

Anyway, this project is to get an indeterminate amount of values from a file, store them in variables, and output them in a "receipt" layout. I decided the best way to do this would be structs and vectors

struct Item {
    string itemName;
    double itemPrice;
    bool taxable;
}


vector<Item> itemList;

Now that I have my struct and my vector set up in my program, I'm trying to read from the file using getlines.

int vectorNumber = 0;
while(!inFile.eof()){
    itemList.resize(vectorNumber+1);

    string tempDouble;
    string tempBool;

    getline(inFile, itemList[vectorNumber].itemName);

    getline(inFile, tempDouble);
    itemList[vectorNumber].itemPrice = stod(tempDouble);

    getline(inFile, tempBool);
    itemList[vectorNumber].taxable = tempBool == "Y" ? true : false;

    vectorNumber++;
}

The reason I'm doing itemList.resize(vectorNumber + 1) is because I was getting a vector subscript out of range on the first getLine. I figured it was because the vector was blank, but I don't know for sure. Anyway, after I added that line, the program was able to move on, but now on the line with the stod, I'm getting an Unhandled exception at [hexValue] in [exe]: std::invalid_argument at memory location [hexValue].

I added a temporary cout << tempDouble before the faulty stod line to see if it was actually pulling a value, and it is. So my question is why am I getting this weird error?

If I comment out everything from the second getline to the ?: line, the program runs successfully, so it's just this one thing I need help fixing. What am I doing wrong? The value it's pulling from the file (I checked it using cout) is 2.49, with an endline character after it. I know getline discards the endline character, but I figured I'd just tell you.

Thank you!

EDIT: I've been asked to see a minimal version of the code that still gives me problems, so here we are:

// TestApplication.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <string>

using namespace std;

struct Item {
    string itemName;
    double itemPrice;
};

vector<Item> itemList;


int main()
{
    ifstream inFile;
    inFile.open("HW3_Data.txt");
    int vectorNumber = 0;
    while (!inFile.eof()) {
        itemList.resize(vectorNumber + 1);

        string tempDouble;
        string tempBool;

        getline(inFile, itemList[vectorNumber].itemName);

        getline(inFile, tempDouble);
        itemList[vectorNumber].itemPrice = stod(tempDouble);

        vectorNumber++;
    }
}

Because I have a feeling this has to do with the file itself and not the program, here is the file:

Bread
2.49
Y
Milk
1.89
N
Eggs, dozen
0.97
N
Apples
4.75
Y
Bananas
1.69
Y
Peanut Butter
2.49
Y

I copied and pasted the file straight into here. There is another line underneath the Y in the last line of the file, that is not an extra return I added in.

user4581301
  • 29,019
  • 5
  • 26
  • 45
TerrorByte
  • 39
  • 5
  • `while(!inFile.eof())` is evil. More on that here: [Why is iostream::eof inside a loop condition considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – user4581301 Feb 14 '18 at 05:31
  • 1
    Recommend using `push_back` rather than `resize`. `vector`s managing their size for you is part of their gig. – user4581301 Feb 14 '18 at 05:33
  • I don't have a good answer for the double conversion failing. Could we get a [mcve]? – user4581301 Feb 14 '18 at 05:40
  • Wait a sec. Looking down a couple lines we get `itemList[vectorNumber].taxable = tempBool ? true : false;`, and I don't think that's going to compile. – user4581301 Feb 14 '18 at 05:57
  • Since I can't post that much information in a tiny comment, I've edited the original post with the requested information on the end. Also, the line you said wouldn't compile, I made a typo copying it over to here. It's actually `itemList[vectorNumber].taxable = (tempBool == "Y" ? true : false);` – TerrorByte Feb 14 '18 at 05:57
  • Right way to do it. Comments turn code formatting into garbage, and I think this is by design Question details should be in the question where they're in your face. – user4581301 Feb 14 '18 at 05:58
  • The new minimal version of the program I built, the tempDouble value is returning as `2.49Milk` and I have no idea why since there should be a Y in between those values. I'm so confused... – TerrorByte Feb 14 '18 at 06:05
  • I've played a little fast and lose with your example, https://ideone.com/4IHePi, and everything looks like it works. But look what happens thanks to the `while (!eof)` bug I brought up in the first comment if I so much as add an extra line to the input: https://ideone.com/5v6e4i – user4581301 Feb 14 '18 at 06:16
  • That's cool that that works, however the project was to get an indeterminate amount of values, and a hard-coded file work with that. I fixed the eof problem, and it still persists to fail the conversion. – TerrorByte Feb 14 '18 at 06:22
  • To go back to the file, pull out the `stringstream` and put the file and file open back in. I used the stream for the demo becasue I can't use a file on that site. Anyway, the only out-and-out bug I see in your code is `while (!eof)` – user4581301 Feb 14 '18 at 06:24
  • I have to apologize. It turns out it was the eof thing. I'm on my colleges virtual machine server since I use a Mac. It's a long story to why I have a virtual machine, but anyway the IDE must've done something weird. I have a working system now, thank goodness. Everything is working (I think!). I'll do some more testing to make sure everything is good. Thanks for your help! – TerrorByte Feb 14 '18 at 06:27
  • One last ball of suggestions. 1 Make and use a `>>` overload to read `Item`s. It makes the the read loop dead simple. 2 Always check IO transactions to make sure they succeeded. Make sure you check before you make decisions on the result of the transaction. 3 https://ideone.com/kHr4Ry – user4581301 Feb 14 '18 at 06:47

0 Answers0