-1

This is the file that I need to read.

Coca-Cola,0.75,20
Root Beer,0.75,20
Sprite,0.75,20
Spring Water,0.80,20
Apple Juice,0.95,20

I need each of this to be into a variable. For example drinkName, drinkCost, drinkQuantity. I'm using c++, please help me.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
Yudiel Curbelo
  • 116
  • 1
  • 9
  • Large parts of the answers were invalid because the question was poorly formatted. With the formatting corrected, it becomes apparent that reading the data is rather a different (and simpler) matter than it previously appeared. – Jerry Coffin Apr 22 '12 at 23:09

3 Answers3

6

I recommend bundling these three variables into a single data type. Lets call it "DrinkT".

struct DrinkT{
    std::string name;
    float cost;
    unsigned int quantity;

    DrinkT(std::string const& nameIn, float const& costIn, unsigned int const& quantityIn):
    name(nameIn),
    cost(costIn),
    quantity(quantityIn)
    {}
};

This has many advantages.
You will now be able to create drinks like this:

DrinkT coke("Coca-Cola",0.75,20);

and access the variables like this:

std::cout << coke.name << std::endl;     //outputs: Coca-Cola
std::cout << coke.cost << std::endl;     //outputs: 0.75
std::cout << coke.quantity << std::endl; //outputs: 20

A drink object will only hold what you have specified: a drink name, a drink cost, and a drink quantity.
The object has a constructor that takes all three of these values on construction.
This means, you can only create a drink object if you specify all of it's values at the same time.

If your going to be storing a lot of drink objects(and you may not know how many), we may also want to put them into some kind of container.
A vector is a good choice. A vector will grow to account for as many drinks as you want to store.

Let's loop through the file, read in the three values individually, and store them in our vector. We will do this again and again for each drink until we reach the end of the file.

int main(){

    std::ifstream infile("file.txt");
    std::vector<DrinkT> drinks;

    std::string name;
    std::string cost;
    std::string quantity;

    std::getline(infile,name,',');
    std::getline(infile,cost,',');
    std::getline(infile,quantity,' ');

    while (infile){
        drinks.push_back(DrinkT(name,atof(cost.c_str()),atoi(quantity.c_str())));

        std::getline(infile,name,',');
        std::getline(infile,cost,',');
        std::getline(infile,quantity,' ');
    }


    //output
    for(DrinkT drink : drinks){
        std::cout << drink.name << " " << drink.cost << " " << drink.quantity << std::endl;
    }

    return EXIT_SUCCESS;
}

compiled with g++ -std=c++0x -o main main.cpp

information on some of the language features used:
http://www.cplusplus.com/reference/string/getline/
http://www.cplusplus.com/reference/stl/vector/

Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271
3

In some (but definitely not all) ways, my advice is roughly similar to @Xploit's. I would start by defining a struct (or class, if you prefer) to hold the data:

struct soft_drink { 
    std::string name;
    double price;
    int quantity;
};

Then (a major difference) I'd define operator>> for that class/struct:

std::istream &operator>>(std::istream &is, soft_drink &s) { 
    // this will read *one* "record" from the file:

    // first read the raw data:
    std::string raw_data;
    std::getline(raw_data, is);
    if (!is)
        return is; // if we failed to read raw data, just return.        

    // then split it into fields:
    std::istringstream buffer(raw_data);

    std::string name;
    std::getline(buffer, name, ',');

    double price = 0.0;
    buffer >> price;
    buffer.ignore(1, ',');

    int quantity = 0;
    buffer >> quantity;

    // Check whether conversion succeeded. We'll assume a price or quantity 
    // of 0 is invalid:
    if (price == 0.0 || quantity = 0)
        is.setstate(std::ios::failbit);

    // Since we got valid data, put it into the destination:
    s.name = name;
    s.price = price;
    s.quantity = quantity;
    return is;
}

This lets us read one record from the input stream and know whether the conversion succeeded or not. Once we have code to read one record, the rest becomes almost trivial -- we can just use a pair of istream_iterators of the correct type to initialize a vector of data:

// read the data in one big gulp (sorry, couldn't resist).
//
std::vector<soft_drink> drink_data((std::istream_iterator<soft_drink>(infile)), 
                                    std::istream_iterator<soft_drink>());
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • Great pun, haha! I just wonder if some of this is too complicated, if this is a beginner and he's working on homework I wonder if some of it will be over his head. – Joe Apr 23 '12 at 02:12
1

Start by investigating how to separate one item from the others:

How to split a string in C++? (through spaces)

After that you are going to have a new string with the format: drinkName,drinkCost,drinkQuantity

If you think about it, what separates each info of the item is the symbol , (comma), so you need to check this post, since it shows how to split by comma as well.

To assist on storing this info, you could create a new data type (class) that has 3 variables:

class Drink
{
public:
    std::string name;
    std::string value;     // or float
    std::string quantity;  // or int
};

At the end, you could have a nice std::vector<Drink> with all the information inside.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
karlphillip
  • 92,053
  • 36
  • 243
  • 426
  • He is right. You have a lot of freedom on how you want to read in your data. You could read in all 3 values as a string and then parse the string by looking for commas. You could follow my example by reading them in separately as strings and then converting them to the appropriate types. – Trevor Hickey Apr 22 '12 at 23:04