i/o stream iterators

Hello,

Please take a look at the example code below:

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
#include <std_lib_facilities_4.h>
using namespace std;

int main() 
{
	string from, to;
	cin >> from >> to;

	ifstream is{ from };
	ofstream os{ to };

	istream_iterator<string> ii{ is };
	istream_iterator<string> eos;
	ostream_iterator<string> oo{ os, "\n" };

	vector<string> b{ ii,eos };
	sort(b.begin(), b.end());
	copy(b.begin(), b.end(), oo);

	for (auto const& b1 : b)
		cout << b1;

	cout << endl;

	system("pause");
	return 0;
}


Here we have two strings populated by input (cin) as, say, fisrtplace and secondplace.
In line 9 and 10 we assign a file-stream-for-reading/writing named is and os respectively. In line 12 we assign an istream-iterator to is named ii. And another to (?) named eos in line 13.

In 14 we set an ostream-iterator to os named oo. What do we use a "\n" there?

Then we have a vector named b initialized with two iterators ii and eos.
We sort (sort what?) in line 17.

And in 18 we copy the vector from its beginning to its end to oo. But in essence, when I print the vector nothing is sorted and nothing is entered either!


Was my thoughts above correct?
And why does the vector not have any input please?



Last edited on
Here we have two strings populated by input (cin) as, say, fisrtplace and secondplace.
In line 9 and 10 we assign a file-stream-for-reading/writing named is and os respectively.
The user enters the input and output filenames respectively. is and os are opened for read / write using the user-supplied filenames.

In line 12 we assign an istream-iterator to is named ii. And another to (?) named eos in line 13.
The iterator ii is set to the start of the input file is. The iterator eos is default-constructed to end-of-stream.

In 14 we set an ostream-iterator to os named oo. What do we use a "\n" there?
"\n" is the delimiter, to separate each item written to the output.

Then we have a vector named b initialized with two iterators ii and eos.
The vector is filled with whatever is contained in the range specified by the two iterators, that is from start of the input file to its end.

We sort (sort what?) in line 17.
b is sorted. That is the the vector declared on the previous line.

And in 18 we copy the vector from its beginning to its end to oo.
That is, all the strings in the vector b are written to the output file, separated by a newline "\n".

But in essence, when I print the vector nothing is sorted and nothing is entered either!

Was my thoughts above correct?
And why does the vector not have any input please?

Your thoughts were mostly correct at one level. I'm not sure you expressed the meaning of what the code was intended to achieve. i.e. get the filenames from the user, read all the strings from one file into a vector, sort it, write the words out to another file, and display the words on the console.


Are you sure you supplied a valid name for the input file?
Last edited on
Since here we actually don't have files, I think we both meant "strings" by "files". I've supplied the name "from" for the input file/string which is opened (for reading) by is and then it's also used by the istream-iterator ii for iteration. Then the vector is filled with the input (a string "firstplace"), is sorted (no change is made), and that input (the string "firstplace") is copied to oo (which points to the string "secondplace" and will override it). Now seemingly we must have that input file (the string "firstplace") on the console window, but the vector prints nothing.

I tried to express what I got from the code but still don't know the reason for the not-printing. :(
Last edited on
I'm sorry, I don't think I understand what you mean.

I asked this question:
Chervil wrote:
Are you sure you supplied a valid name for the input file?


and the response began:
Frank14 wrote:
Since here we actually don't have files,


Does that mean "No"?

@OP: Are you aware that std::ifstream and std::ofstream are for file I/O ?

I suggest you look up the documentation for those classes - and, in particular, their constructors - and rethink your interpretation of the code.
Maybe this will help.

I added some extra cout statements. Also added checks that the files are actually being opened - if they aren't, it means there is nothing for the rest of the program to process.

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <iterator>
#include <vector>
#include <algorithm>

using namespace std;

int main() 
{
    string from, to;
    cout << "Please enter name of input file\n"
            "The file must already exist\n"
            "and should contain several words\n";
    cin >> from;
    ifstream is{ from };
    
    if (!is)
    {
        cout << "Could not open file: " << from << "\nprogram terminating" << endl;
        system("pause");       
        return 1; 
    }
        
    cout << "\nPlease enter name of output file\n"
            "If the file already exists it will be replaced \n";    

    cin >> to;
    
    ofstream os{ to };

    if (!os)
    {
        cout << "Could not open file: " << to << "\nprogram terminating" << endl;
        system("pause");       
        return 1; 
    }
    
    istream_iterator<string> ii{ is };
    istream_iterator<string> eos;
    ostream_iterator<string> oo{ os, "\n" };

    cout << "\nAttempting to read from file " << from << '\n';
    vector<string> b{ ii,eos };
    cout << "Number of words read = " << b.size() << '\n';

    cout << "Sorting...\n";    
    sort(b.begin(), b.end());

    cout << "\nWriting sorted words to output\n";
    copy(b.begin(), b.end(), oo);

    cout << "\nThese are the words after sorting:\n";
    for (auto const& b1 : b)
        cout << b1 << ' ';

    cout << endl;

    cout << "\nProgram finished" << endl;
    system("pause");
    return 0;
}


There's also an overview of ifstream and ofstream in the tutorial here:
http://www.cplusplus.com/doc/tutorial/files/
Last edited on
Thank you, and sorry for the inconvenience. I thought we could use fstream not only for files but for strings as well. But I got that they are "only" for files.

For the code, thanks. For example we have a file named firstplace.txt on the Desktop. We should somehow give the address of that file to ifstream to be opened for reading. And by just giving its name to cin, it can't access that file I think.

I know using for example:
ifstream is{ "C:\Users\Me\Desktop\firstplace.ext" };
that file will be opened for reading by is. But I don't know the role of the strings and how to use them in the example.
The strings are the names of the files!

Look at the documentation for the constructors of those classes, as I suggested. If you pass a string into the constructor, that string is the file name.
What documentation? If you meant the link Chervil suggested, I did.
There's ample reference documentation right here on this site:

http://www.cplusplus.com/reference/

Also, cppreference is an excellent site - possibly even better than this one for reference documentaion:

http://en.cppreference.com/w/
Let it go. Never mind. I will find answers on some other forum.
What answers? Chervil has explained the program completely. And when you asked for good sources of C++ reference documentation, you got those too.

What answers do you think you haven't been given yet?
Registered users can post here. Sign in or register to post.