0

I am experimenting with reading input from command line and successfully store them in objects attributes.

Example of input (./(nameOfExecutable) < (sourceText) in the command line)

20 5
1 5
28 5
2 5
20 5
4 5
22 5
88 3
27 5
34 5

I want to read and store them into object attributes.

experimentClass.h

#ifndef EXPERIMENTCLASS_H
#define EXPERIMENTCLASS_H

#pragma once

class experimentClass
{
public:
    experimentClass(int x, int y);
    ~experimentClass();

private:
    int age;
    int favoriteNumber;
};

#endif

experimentClass.cpp

#include "experimentClass.h"

experimentClass::experimentClass(int x, int y)
{   
    age = x;
    favoriteNumber = y;    
}

experimentClass::~experimentClass()
{

}

main.cpp

#include <iostream>
#include "experimentClass.h"
using namespace std;

int main(){
    
    int age;
    int favoriteNumber;

    std::cin >> age;
    std::cin >> favoriteNumber;
    experimentClass a(age, favoriteNumber);   
}

In this case, I am able to store 20 into a's age, 5 into a's favoriteNumber.

However, I want to do this process until it hits the end of input.

So, in this case, I want to create 10 objects with given input, using iteration, and store these object into an array or something.

How can I read them properly so that I can achieve this?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Hayato
  • 61
  • 1
  • 6
  • 1
    Are you familiar with `std::vector`? What did you mean, exactly, by "read them properly"? – Sam Varshavchik Mar 25 '22 at 00:30
  • 1
    What you are currently doing to read looks pretty good. Only thing I'd change is popping it in a loop (`while (std::cin >> age >> favoriteNumber) { do stuff here }`) and stuffing what you read in one of those `vector` thingies Sam's talking about. – user4581301 Mar 25 '22 at 00:35
  • A quick piece on why the reading is done in the while loop's exit condition: [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – user4581301 Mar 25 '22 at 00:38
  • If you find yourself needing more control/better error checking (for example, what if someone puts THREE inputs on one line?) Give [Read file line by line using ifstream in C++](https://stackoverflow.com/questions/7868936/read-file-line-by-line-using-ifstream-in-c), particularly option 2 of the top-voted answer, a read – user4581301 Mar 25 '22 at 00:42
  • @user4581301 I tried the way you typed, and it works exactly how I wanted to be!!! Thank you so much. – Hayato Mar 25 '22 at 00:50

3 Answers3

1

Simply take the logic you already have and put it inside a loop, eg:

#include <iostream>
#include <vector>
#include "experimentClass.h"
using namespace std;

int main() {
    
    int age;
    int favoriteNumber;
    vector<experimentClass> vec;

    while (cin >> age >> favoriteNumber) {
        experimentClass a(age, favoriteNumber);
        vec.push_back(a);
    }
   
    // use vec as needed...
}

Then you can take this a step further by implementing an operator>> for your class, eg:

#ifndef EXPERIMENTCLASS_H
#define EXPERIMENTCLASS_H

#include <istream>

#pragma once

class experimentClass
{
public:
    experimentClass(int x = 0, int y = 0);

    friend std::istream& operator>>(std::istream &is, experimentClass &cls);

private:
    int age;
    int favoriteNumber;
};

std::istream& operator>>(std::istream &is, experimentClass &cls);

#endif
#include "experimentClass.h"

experimentClass::experimentClass(int x, int y)
{   
    age = x;
    favoriteNumber = y;
}

std::istream& operator>>(std::istream &is, experimentClass &cls)
{
    return is >> cls.age >> cls.favoriteNumber;
}
#include <iostream>
#include <vector>
#include "experimentClass.h"
using namespace std;

int main() {
    
    experimentClass a;
    vector<experimentClass> vec;

    while (cin >> a) {
        vec.push_back(a);
    }
   
    // use vec as needed...
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
0

You could model the input line with a struct:

struct Record
{
    unsigned int m_age;
    int          m_favorite_number;
};

Then overload the operator>>:

struct Record
{
    unsigned int m_age;
    int          m_favorite_number;
    friend std::istream& operator>>(std::istream& input, Record& r);
};
std::istream& operator>>(std::istream& input, Record& r)
{
    input >> r.m_age;
    input >> r.m_favorite_number;
    return input;
}

You could read in the data into a database by using:

std::vector<Record> database;
Record r;
while (std::cin >> r)
{
    database.push_back(r);
}  

In the above call, you could replace std::cin with a file stream.

You could print or display a record from the database:

std::cout << database[3].m_age << " " << database[3].m_favorite_number << "\n";

Although IMHO, you should overload operator<< to print the record in a default format.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
-1

Since you are using nameOfExecutable.exe < source.txt, you can use cin.eof to check if the end of file is reached:

while(true){
    int a, b;
    std::cin >> a;
    if(std::cin.eof()){
        break;
    }
    std::cin >> b;
    //Create Class
}
QWERTYL
  • 1,355
  • 1
  • 7
  • 11