Home > Enterprise >  C how to handle file with multiple data types?
C how to handle file with multiple data types?

Time:11-22

I have an input txt file which contains information like this:

    4
    Eric Nandos
    3
    15.00 45.00 36.81 64.55 50.50
    51.52 36.40 25.15 35.45 24.55
    41.55 44.55 36.35 55.50 40.55
    Steven Abraham
    2
    40.45 20.35 40.46 30.35 55.50
    18.25 18.00 20.00 30.00 60.65
    Richard Mccullen
    2
    40.45 50.55 20.45 30.30 20.25
    30.00 20.00 40.00 60.60 45.45
    Stacey Vaughn
    3
    45.00 25.00 15.00 30.30 25.20
    20.20 60.65 55.55 50.50 50.40
    30.30 60.55 20.25 20.00 40.00

With getline(file, string) I am able to store this data into a string variable and then output it. The problem is, I need to store the different data types into different variables in order to do certain operations with them (ex: I need to average the decimal values, add the different int values, store some data into a vector, etc). I've tried different loops to parse through the file, but I've been getting an error every time. Any advice on how to separate the different data here so I can store them accordingly? I'm still new to C so I don't have much experience. Thank you.

CodePudding user response:

The first line specifies the number of records in the file, where each individual record then consists of:

  • 1 line for a person's name

  • 1 line specifying the number of following lines

  • N number of lines of floating-point numbers

You can read such data like this:

#include <fstream>
#include <sstream>
#include <string>
#include <limits>

...

int numRecords, numLines;
std::string name, line;
double value;

std::ifstream file("filename.txt");
if (!file.is_open()) {
    // error handling...
}

if (!(file >> numRecords)) {
    // error handling ...
}

file.ignore(std::numeric_limits<streamsize>::max(), '\n');

for (int i = 0; i < numRecords;   i)
{
    if (!std::getline(file, name)) {
        // error handling...
    }

    // use name as needed...

    if (!(file >> numLines)) {
        // error handling...
    }

    for (int j = 0; j < numLines;   j)
    {
        if (!std::getline(file, line)) {
            // error handling...
        }

        std::istringstream iss(line);
        while (iss >> value) {
            // use value as needed...
        }
        if (iss.fail()) {
            // error handling...
        }
    }
}

CodePudding user response:

Here is what I got:

/// copyright 2021 viraltaco_ <https://opensource.org/licenses/MIT>
#include <vector>    // vector, begin, end
#include <string>    // obvious
#include <utility>   // move
#include <iostream>  // cin
#include <iterator>  // istream_iterator
#include <algorithm> // copy_n

#include <cstddef>   // size_t

class Customer {
protected:
  std::string name_;
  std::vector<float> payments_;

public:
  explicit Customer(std::string name, const std::size_t lines)
    : name_{ std::move(name) }
    , payments_{ }
  {
    payments_.reserve(lines);
    using in_iter = typename std::istream_iterator<float>;
    std::copy_n(in_iter(std::cin), lines, back_inserter(payments_));
  }
};


auto main() -> int {
  
}

Here is the live version on Compiler Explorer
I'm starving, though so you'll need to figure out the rest.
PS: I do realize that the vector of float could very much be a vector of words (4 bit per digit should do) in this case

EDIT: Forgot to mention… I used std::cin because I didn't really have time to think more about it. But you can use any std::istream. (You'll need to pass it in).

  • Related