0

Ok. So I'm trying to read from a file and put the information into a class. Let me explain:

Let's say I have a txt file that looks like this

1 2 3 4 5 6 7 8 

Now let's say I have a class

class Numbers { public: Numbers(int first, int second, int third, int fourth) : first(first), second(second), third(third), fourth(fourth){} private: int first; int second; int third; int fourth; }; 

Now, I want to have each row of the file be a new instance of Numbers, and the numbers in each row to be used as data members for each instance (hope that made sense).

So after reading from the above file I should have two instances of Numbers. The first one containing (1, 2, 3, 4) and the second containing (5, 6, 7, 8). I have a function that converts the string to an int after reading from the file. I'm mostly having trouble creating the instances of Numbers. Any ideas?

2
  • since C++ reads files line by line you probably have to store the values in an array or vector first. for example a std::vector<std::vector<int>> could be used to store the numbers just as they are in the file, and then afterwards use those values for creating your objects Commented Nov 3, 2013 at 19:50
  • I recommend you search StackOverflow for "[c++] parse file input" to get some examples of extracting numbers from a file. Commented Nov 3, 2013 at 20:11

3 Answers 3

2

Why don't you just load all the numbers into a vector like this?

#include <iterator> #include <fstream> #include <vector> #include <iostream> std::vector<int> loadNumbersFromFile(const std::string& name) { std::ifstream is(name.c_str()); if (!is) { std::cout << "File could not be opened!" << std::endl; } std::istream_iterator<int> start(is), end; return std::vector<int>(start, end); } void main() { std::vector<int> numbers = loadNumbersFromFile("file.txt"); } 

No need to declare a class for that.

Sign up to request clarification or add additional context in comments.

Comments

0

You don't need to convert anything because basic_istream& operator>>(int&) already does this for you

ifstream f; f >> first; 

Creating a Numbers instance can be as simple as defining a constructor

Numbers() : first(0), second(0), third(0), fourth(0) {} 

and then

Numbers number1, number2; 

and when you define a

friend istream &operator>>(istream &f, Number &n) { f >> n.first >> n.second >> n.third >> n.fourth; return f; } 

you can just say

f >> number1 >> number2; 

Comments

0

As others have pointed out, the input operator for int already does the conversion from a sequence of digits to an int. However, this conversion also does something which may or may not be the Right Thing: the formatted input operators do skip leading whitespace, not distinguishing between different sorts of whitespace. That is, if one line contains fewer values than expected, the stream will happily read them from the next line! Whether this the correct behavior or not depends on the exact use. Since the question specifically mentioned the format containing four values on each line, I'll assume that it is not OK to have fewer than 4 values on each line.

Preventing the input operators from automatically skipping whitespace can be done using std::noskipws. Once this is applied it become necessary to skip the whitespace explicitly, though. Skipping whitespace but no newlines can be done using a custom manipulator:

std::istream& skipspace(std::istream& in) { std::istream::sentry cerberos(in); if (in) { std::istreambuf_iterator<char> it(in), end; while (it != end && *it != '\n' && std::isspace(static_cast<unsigned char>(*it))) { ++it; } } return in; } 

With a manipulator like this, it is fairly straight forward to implement reading a line of values and to fail if there are not enough values:

  1. Turn off automatic skipping of whitespace.
  2. Skip leading whitespace using std::ws to get rid of the previous line end and possible leading whitespace on the line.
  3. Read each value, skipping only non-newlines between the objects.

That is, an input operator for the class Numbers would look like this:

std::istream& operator>> (std::istream& in, Numbers& numbers) { int first, second, third, fourth; if (in >> std::noskipws >> std::ws >> first >> skipspace >> second >> skipspace >> third >> skipspace >> fourth) { numbers = Numbers(first, second, third, fourth); } return in; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.