1

So the goal is to read a line from a file that looks like this

N,1234,box,kg,1,123.45,1,5

each data type is separated by a ',' all I need to do is to split it.

For example the first would be char = N.

Seconds would be int = 1234 and so on...

std::fstream& Product::load(std::fstream& file) {
    char sku_[max_sku_length + 1];
    char name[max_name_length + 1];
    char unit[max_unit_length + 1];
    double price_;
    char taxed_, type, skip;
    int  quantity, qtyNeeded;
    file >> type >> skip;
    file >> sku_ >> skip; 
    file >> name >> skip;
    file >> unit >> skip;
    file >> taxed_ >> skip;
    file >> price_ >> skip;
    file >> quantity >> skip;
    file >> qtyNeeded >> skip;
    Product tmpObj(sku_, name, unit, quantity, taxed_ != 0, price_, qtyNeeded);
    tmpObj.type_ = type;
    *this = tmpObj;
    return file;
}

This is my current function that I have for this. The problem I have is that it doesn't split off at the comma and instead will write it so my char arrays look like "g,1,123.4"

Bot
  • 59
  • 8
  • 1
    Sometimes you have to do all the work yourself. Use the right tool for the right job. `>>` is the wrong tool for this. Your input consists of individual lines. There's only one function that reads a single line from a file stream: `std::getline`. Now you've read a single line, and it's sitting in the string. Now, write a little bit of code that searches through the string, and extracts each individual field from it. It's not hard. `std::string` has many useful methods, like `find()`, and `substr()`, for this. Now you got each individual field, and ***now*** use `>>` to convert it to a number. – Sam Varshavchik Apr 16 '18 at 00:44
  • [std::getline](http://en.cppreference.com/w/cpp/string/basic_string/getline) has a third parameter, delimiter. It will split the line for you if it encounters a `,` or a `newline`. – super Apr 16 '18 at 00:45
  • Which is great, if all your input is always well-formed, and each line contains the right number of fields. But we do not live in a perfect world. Sometimes you get crap with fewer, or more fields, and ab-using `std::getline` like that will create a huge dumpster fire that you will now have to put out. Was that really worth it? – Sam Varshavchik Apr 16 '18 at 00:46
  • Here is a great discussion on [spiting strings](https://stackoverflow.com/questions/236129/the-most-elegant-way-to-iterate-the-words-of-a-string) – lakeweb Apr 16 '18 at 00:48
  • @SamVarshavchik I don't see any reason why it would be easier to validate the data just because you use one way or the other. That would depend on the data and how it should be validated. – super Apr 16 '18 at 00:50
  • Based on prior examples I've read here, on stackoverflow.com, of using `std::getline` in this manner -- after reading them over it rarely takes me more than a moment to think of invalid input that will make the sample code blow chunks, and crash. You can certainly do it that way. But the end result is typically fragile, and beating it into the proper shape to handle invalid input is a lot of work. Parsing the whole line, and extracting fields yourself, offers more control and better grasp on the whole process, and results in much easier, and more reliable, error recovery. – Sam Varshavchik Apr 16 '18 at 00:55
  • @SamVarshavchik But what if a single, uppercase char always starts a valid input and that can't be seen anywhere else in the fields. It's just an example of a case when it would be **more safe** to use the simple getline with delimiter. It would not miss input that's been accidentally split on several lines. – super Apr 16 '18 at 01:23

0 Answers0