Using iterators to read data from file.

I have a code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <cstdio>


using namespace std;

int main()
{
    
    int mnumbers[10];
    int mnumbers2[10];
    FILE * file;
    int value = 0;

    cout << "Enter 10 numbers: ";
    for(int i = 0; i < 10; i++){
        cin >> value;
        mnumbers[i] = value;
    }

    file = fopen("text.txt", "r+b");
    fwrite(mnumbers,4,10,file);
    fclose(file);

    for(int i = 0; i < 10; i++){
        cout << mnumbers[i] << " "  ;
    }

    file = fopen("text.txt", "r+b");
    fread(mnumbers2,4,10,file);
    fclose(file);

    for(int i = 0; i < 10; i++){
        cout << mnumbers2[i] << " "  ;
    }

    return 0;
}




Which asks user to input 10 int values and write those values to binary file. Later i read those same ints from file to array and output them to console. It works fine. But the task is a bit different. I need to use iterator and read from file to console using iterator. I think i also should overload ++ and -- but i cant figure out how to do that.
The question is what is actually meant by 'iterator'. You may output this in another way:
1
2
3
4
5
    int *begin_iterator = mnumbers;
    int *end_iterator = mnumbers + 10;
    for(int *iterator = begin_iterator; iterator != end_iterator; ++iterator){
        cout << *iterator << " "  ;
    }
This would come close to iterator handling.
Streams do have some iterators:
https://www.working-software.com/simple-stl-io
Which asks user to input 10 int values and write those values to binary file[/b]. Later i read those same ints from file to array and output them to console. It works fine. But the task is a bit different. I need to use iterator and read from file to console using iterator.

This isn't my strongest area, so I'm willing to be corrected. But as far as I can tell, accessing a binary file using iterators may need some extra effort, as opposed to using an iterator to read (say) integers from a text file which is fairly straightforward.

Anyway, my example, where I introduced a struct named my_int as the intermediary.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <fstream>
#include <iterator>

using namespace std;

const int size = 10;

void create_file(const char * fname)
{
    int numbers[size] = { 53, 59, 61, 67,  71, 73, 79, 83, 89, 97 };    
    ofstream fout(fname, ios::binary);
    fout.write(reinterpret_cast<const char *>(numbers), size * sizeof(int));
}

struct my_int {
    int n;
};

istream & operator >> (istream & is, my_int & m)
{
    is.read(reinterpret_cast<char *>(&m.n), sizeof m.n);
    return is;
}

int main()
{
    // First generate a file containing the binary data
    create_file("test.bin");

    // now attempt to read it back in.
    ifstream fin("test.bin", ios::binary);    
    if (!fin)
    {
        cout << "file not open\n";
        return 1;
    }
        
    istream_iterator<my_int> eos;
    istream_iterator<my_int> itr(fin);
    
    while (itr != eos)
    {
        cout << itr->n << '\n';
        ++itr;
    }   
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# include <iostream>
# include <iterator>
# include <fstream>
# include <vector>
# include <algorithm>

constexpr auto SIZE = 10;

const std::string fileName = "F:\\numbers.txt";

int main()
{

   std::vector<int> numbersVec{};

    std::generate_n(std::back_inserter(numbersVec), SIZE,
        []()
        {
            return *(std::istream_iterator<int>(std::cin));
        }
    );//read numbers from std::cin into std::vector<int> using the std::istream_iterator<int>

    std::ofstream myFileOf{fileName, std::ios::out | std::ios::binary};
    //create the std::ofstream object (binary mode) to write to

    std::copy(numbersVec.cbegin(), numbersVec.cend(),std::ostream_iterator<int>(myFileOf, " "));
    //write the numbers from the vector to the ofstream object with an std::ostream_iterator<> associated with the ostream ofstream object


    myFileOf.close();
    //done writing, now close the file

    std::ifstream myFileIn{fileName, std::ios::in | std::ios::binary};
   //create std::ifstream object associated with the file, also in binary mode
    std::copy(std::istream_iterator<int>{myFileIn}, std::istream_iterator<int>{}, std::ostream_iterator<int> (std::cout, " "));
    //read the numbers from the file to std::cout with an std::ostream_iterator<int> associated with std::cout with space b/w numbers
}

edit: use std::ostream_iterator<int>, not <char> on line 26 to include multi-digit numbers
Last edited on
could also re-direct the stream buffer associated with std::cout to the file and thereby avoid using std::vector<int> or any other container to store the input numbers first:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# include <iostream>
# include <iterator>
# include <fstream>
//# include <vector>
# include <algorithm>

constexpr auto SIZE = 4;

const std::string fileName = "F:\\numbers.txt";

int main()
{
    std::ofstream myFileOf{fileName, std::ios::out | std::ios::binary};
    //create the std::ofstream object (binary mode) to write to

    std::cout << "enter " << SIZE << " numbers: \n";
    std::streambuf *coutbuf = std::cout.rdbuf(); //save existing cout buffer
    std::cout.rdbuf(myFileOf.rdbuf()); //redirect std::cout buffer to the std::ofstream object
    size_t i{};
    while (i < SIZE)
    {
        int number{};
        std::cin >> number;
        std::cout << number << " ";
        ++i;
    }
    std::cout.rdbuf(coutbuf); //reset to standard output again
    myFileOf.close(); //close the file

    std::ifstream myFileIn{fileName, std::ios::in | std::ios::binary};
    //create std::ifstream object associated with the file, also in binary mode

    std::copy(std::istream_iterator<int>{myFileIn}, std::istream_iterator<int>{}, std::ostream_iterator<int> (std::cout, " "));
    //read the numbers from the file to std::cout with an std::ostream_iterator<int> associated with std::cout with space b/w numbers
}
Topic archived. No new replies allowed.