Input Streams

Creating Objects from Stream

How do I create a dynamic array of objects from stream data?

Abstract art representing computer programming

Creating a dynamic array of objects from stream data involves reading the input in a loop and constructing objects based on the extracted data. This technique is useful for processing structured input data, such as records in a file or user input.

Example with a Simple Class

Consider a Character class with attributes Name, Level, and isAlive. You can read multiple Character objects from a stream and store them in a std::vector for dynamic sizing:

#include <iostream>
#include <sstream>
#include <vector>

class Character {
 public:
  std::string Name;
  int Level;
  bool isAlive;

  Character(std::istringstream& stream) {
    stream >> Name >> Level >> isAlive;  
  }

  void Log() const {
    std::cout << Name << " - Level " << Level
      << (isAlive ? " (Alive)" : " (Dead)")
      << '\n';
  }
};

int main() {
  std::istringstream input{
    "Legolas 80 1 Gimli 70 1 Aragorn 60 0"};
  std::vector<Character> party;

  while (input) {
    party.emplace_back(input);  
  }

  for (const auto& member : party) {
    member.Log();
  }
}
Legolas - Level 80 (Alive)
Gimli - Level 70 (Alive)
Aragorn - Level 60 (Dead)

In this example, the Character constructor reads data from the stream, and emplace_back() adds a new Character to the std::vector.

Improved Error Handling

For better error handling and ensuring you read valid data, you can use a member function to read from the stream and check its state:

#include <iostream>
#include <sstream>
#include <vector>

class Character {
 public:
  std::string Name;
  int Level;
  bool isAlive;

  bool readFromStream(
    std::istringstream& stream
  ) {
    int alive;
    if (stream >> Name >> Level >> alive) {
      isAlive = (alive != 0);
      return true;
    }
    return false;
  }

  void Log() const {
    std::cout << Name << " - Level " << Level
      << (isAlive ? " (Alive)" : " (Dead)")
      << std::endl;
  }
};

int main() {
  std::istringstream input{
    "Legolas 80 1 Gimli 70 1 Aragorn 60 0"
  };
  std::vector<Character> party;
  Character character;

  while (character.readFromStream(input)) {
    party.push_back(character);
  }

  for (const auto& member : party) {
    member.Log();
  }
}
Legolas - Level 80 (Alive)
Gimli - Level 70 (Alive)
Aragorn - Level 60 (Dead)

This approach ensures that only valid Character objects are added to the vector.

Using std::getline()

If the data is structured across multiple lines or uses custom delimiters, std::getline() can be useful:

#include <iostream>
#include <sstream>
#include <vector>

class Character {
 public:
  std::string Name;
  int Level;
  bool isAlive;

  Character(const std::string& line) {
    std::istringstream stream(line);
    stream >> Name >> Level >> isAlive;  
  }

  void Log() const {
    std::cout << Name << " - Level " << Level
      << (isAlive ? " (Alive)" : " (Dead)")
      << '\n';
  }
};

int main() {
  std::istringstream input{
    "Legolas 80 1\nGimli 70 1\nAragorn 60 0"
  };
  std::vector<Character> party;
  std::string line;

  while (std::getline(input, line)) {  
    party.emplace_back(line);          
  }

  for (const auto& member : party) {
    member.Log();
  }
}
Legolas - Level 80 (Alive)
Gimli - Level 70 (Alive)
Aragorn - Level 60 (Dead)

This example uses std::getline() to read each line of input, creating a Character object from each line.

Creating a dynamic array of objects from stream data allows for flexible and efficient processing of structured input, making it a powerful technique in C++.

This Question is from the Lesson:

Input Streams

A detailed introduction to C++ Input Streams using std::cin and istringstream. Starting from the basics and progressing up to advanced use cases including creating collections of custom objects from our streams.

Answers to questions are automatically generated and may not have been reviewed.

This Question is from the Lesson:

Input Streams

A detailed introduction to C++ Input Streams using std::cin and istringstream. Starting from the basics and progressing up to advanced use cases including creating collections of custom objects from our streams.

A computer programmer
Part of the course:

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, unlimited access

This course includes:

  • 125 Lessons
  • 550+ Code Samples
  • 96% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved