In C++, Input Iterators are a type of iterator that can read elements in a sequence but only move in one direction.
They’re primarily used for reading input data or traversing a container to read values without modifying them.
Input iterators are part of the Iterator category in the C++ Standard Template Library (STL) and are typically used with streams or for single-pass algorithms.
Characteristics of Input Iterators
- Single-pass traversal: Can only be incremented, not decremented, and can only traverse forward.
- Read-only: Can read values from the sequence but cannot modify them.
- Equality comparison: Two input iterators can be compared for equality.
- Dereferenceable: Supports dereferencing to read the current element.
Basic Syntax
iterator_type iterator_name = container.begin();
1. Basic Example of Input Iterator with std::vector
The most common use of input iterators is with containers like std::vector. Here, we’ll use an input iterator to read elements from a vector.
#include <iostream> #include <vector> using namespace std; int main() { vector<int> numbers = {1, 2, 3, 4, 5}; // Input iterator to read elements in the vector for (auto it = numbers.begin(); it != numbers.end(); ++it) { cout << *it << " "; // Dereference the iterator to get the value } return 0; }
Explanation:
- it is an input iterator that reads each element of the vector numbers.
- The *it dereferences the iterator to get the value of the current element.
Output:
1 2 3 4 5
2. Using std::istream_iterator for Stream Input
std::istream_iterator is a type of input iterator used with input streams (like cin or file streams) to read values.
#include <iostream> #include <iterator> #include <vector> using namespace std; int main() { cout << "Enter numbers separated by spaces (non-number to stop): "; // Create an input iterator for reading integers from cin istream_iterator<int> input_it(cin); istream_iterator<int> end_it; vector<int> numbers(input_it, end_it); cout << "You entered: "; for (int number : numbers) { cout << number << " "; } return 0; }
Explanation:
- istream_iterator<int> input_it(cin); initializes an input iterator to read integers from cin.
- The iterator reads values into the vector numbers until it encounters a non-integer input (like a letter or EOF).
Output (example):
Enter numbers separated by spaces (non-number to stop): 5 10 15 20 x You entered: 5 10 15 20
3. Reading from a File using std::istream_iterator
istream_iterator can also be used to read values from files.
#include <iostream> #include <fstream> #include <iterator> #include <vector> using namespace std; int main() { ifstream inputFile("numbers.txt"); if (!inputFile) { cerr << "File could not be opened!" << endl; return 1; } // Create an input iterator to read integers from the file istream_iterator<int> input_it(inputFile); istream_iterator<int> end_it; vector<int> numbers(input_it, end_it); cout << "Numbers in file: "; for (int number : numbers) { cout << number << " "; } inputFile.close(); return 0; }
Explanation:
- inputFile is an ifstream object used to open the file “numbers.txt”.
- istream_iterator<int> input_it(inputFile); reads integers from inputFile until the end of the file.
Sample numbers.txt file:
10 20 30 40 50
Output:
Numbers in file: 10 20 30 40 50
4. Using std::copy with Input Iterators
std::copy is a generic algorithm that can be used with input iterators to copy elements from one container to another.
#include <iostream> #include <iterator> #include <vector> #include <algorithm> using namespace std; int main() { vector<int> numbers = {1, 2, 3, 4, 5}; vector<int> copy_numbers; // Use std::copy with input iterators to copy values copy(numbers.begin(), numbers.end(), back_inserter(copy_numbers)); cout << "Copied numbers: "; for (int number : copy_numbers) { cout << number << " "; } return 0; }
Explanation:
- copy uses numbers.begin() and numbers.end() as input iterators to read values.
- back_inserter is used to append values to copy_numbers.
Output:
Copied numbers: 1 2 3 4 5
5. Summing Elements Using std::accumulate with Input Iterators
The std::accumulate function from <numeric> can be used with input iterators to calculate the sum of elements in a container.
#include <iostream> #include <vector> #include <numeric> using namespace std; int main() { vector<int> numbers = {1, 2, 3, 4, 5}; // Use accumulate with input iterators to calculate sum int sum = accumulate(numbers.begin(), numbers.end(), 0); cout << "Sum of elements: " << sum << endl; return 0; }
Explanation:
- accumulate takes numbers.begin() and numbers.end() as input iterators and calculates the sum of elements starting from 0.
Output:
Sum of elements: 15
6. Using Input Iterator to Read Unique Words from std::istream
This example demonstrates using istream_iterator to read unique words from cin and store them in a set.
#include <iostream> #include <iterator> #include <set> using namespace std; int main() { cout << "Enter words separated by spaces (type 'exit' to stop): "; set<string> uniqueWords; istream_iterator<string> input_it(cin); istream_iterator<string> end_it; while (input_it != end_it) { string word = *input_it; if (word == "exit") break; uniqueWords.insert(word); ++input_it; } cout << "Unique words: "; for (const auto& word : uniqueWords) { cout << word << " "; } return 0; }
Explanation:
- istream_iterator<string> input_it(cin); reads strings from cin.
- Unique words are stored in a set, which automatically removes duplicates.
Output (example):
Enter words separated by spaces (type 'exit' to stop): apple banana apple orange exit Unique words: apple banana orange
7. Filtering Elements with std::copy_if and Input Iterators
std::copy_if can be used to selectively copy elements from a container using input iterators.
#include <iostream> #include <iterator> #include <vector> #include <algorithm> using namespace std; int main() { vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; vector<int> evenNumbers; // Use copy_if to select only even numbers copy_if(numbers.begin(), numbers.end(), back_inserter(evenNumbers), [](int n) { return n % 2 == 0; }); cout << "Even numbers: "; for (int number : evenNumbers) { cout << number << " "; } return 0; }
Explanation:
- copy_if uses numbers.begin() and numbers.end() as input iterators to filter even numbers.
- Only elements that satisfy n % 2 == 0 are copied to evenNumbers.
Output:
Even numbers: 2 4 6 8 10
8. Counting Occurrences with std::count and Input Iterators
The std::count function can be used with input iterators to count the occurrences of a specific value in a container.
#include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { vector<int> numbers = {1, 2, 3, 4, 2, 3, 2, 4, 5}; // Count occurrences of '2' int count_2 = count(numbers.begin(), numbers.end(), 2); cout << "Number of times 2 appears: " << count_2 << endl; return 0; }
Explanation:
- count takes numbers.begin() and numbers.end() as input iterators and counts the occurrences of 2.
Output:
Number of times 2 appears: 3
Summary Table of Input Iterator Usage
Example | Description |
---|---|
Basic Input Iterator with Vector | Reads and prints values from a vector |
Stream Input Iterator | Uses istream_iterator to read values from cin |
File Input Iterator | Reads values from a file using ifstream and istream_iterator |
Copying with std::copy | Uses input iterators to copy values from one container to another |
Summing with std::accumulate | Calculates the sum of elements in a container |
Reading Unique Words | Reads and stores unique words from input into a set |
Filtering with std::copy_if | Selectively copies elements based on a condition |
Counting Occurrences | Counts specific occurrences in a container |
Key Takeaways
- Input Iterators are read-only, single-pass iterators used for traversing a sequence in one direction without modifying it.
- std::istream_iterator is a common input iterator used with streams (cin and ifstream).
- They work well with algorithms like std::copy, std::accumulate, std::copy_if, and std::count.
- Input iterators provide an efficient way to read data from containers or streams while maintaining data integrity (read-only access).