How to reverse a text file

Pages: 12
If we have a text file containing the string: abc, how to reverse it to be cba using file open modes (ios::app, ios::ate, ios::binary, ios::trunc, ios::in and ios::out)?
An easy way to reverse a file is by using stream iterators, std::vector and std::reverse_copy().

Note that this has nothing to do with file open modes.

Also note that the input file will be copied in memory entirely.
This must be done because stream iterators can't go in reverse, unfortunately.

http://www.cplusplus.com/reference/iterator/
http://www.cplusplus.com/reference/algorithm/reverse_copy/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <algorithm>
#include <fstream>
#include <ios>
#include <iterator>
#include <vector>

int main()
{
    std::ifstream input_file("jokes.txt", std::ios_base::binary);
    std::ofstream output_file("jokes.reversed.txt", std::ios_base::binary);
    std::istreambuf_iterator<char> input_begin(input_file);
    std::istreambuf_iterator<char> input_end;
    std::ostreambuf_iterator<char> output_begin(output_file);
    std::vector<char> input_data(input_begin, input_end);

    std::reverse_copy(input_data.begin(), input_data.end(), output_begin);
}
Last edited on
Thank you very much for your reply, but what I need is that I should use the file open modes for that problem because it's an exercise.
Do you know how to do that by those open modes?
To my knowledge, the open modes cannot help you to read (or write) a file in reverse.

A more difficult solution than the above one, is to keep seeking in the input file at offsets from the end to the beginning. Here is some documentation that may help:

http://www.cplusplus.com/reference/istream/istream/seekg/
http://www.cplusplus.com/reference/istream/istream/tellg/

Even if you do this, open modes won't do much for you. In fact you won't even care about them, unless you want to use tellg() (which you don't necessarily need to use) and then you use the open mode std::ios_base::ate when opening the input file.

You should post the text of the exercise, so that we see exactly what you need to achieve.
you can do it with array......
Its very easy with array just reverse the arrangement of array :P
Catfish666:

The text of the exercise is this:
Reverse the order of characters in a text file, For example asdfghjkl becomes lkjhgfdsa. Hint: "file open modes"

And there is a section in this chapter (11) and in that book ( http://www.stroustrup.com/programming.html ) named "Open file modes", which gives us a very small explanation about (ios::app, ios::ate, ios::binary, ios::trunc, ios::in and ios::out).

So, apparently I should use that section (because the author wanted it from me), to solve the exercise.
Last edited on
closed account (Dy7SLyTq)
im pretty sure fstream has nothing that will let you do it, unless he was talking about using ios::in and ios::out to read/write consecutively. you dont even need an array. i would just read keep popping and writing the next character
What book is that excerpt from? I think you're misunderstanding the hint.
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
#include <iostream>
#include <string>
#include <fstream>
#include <algorithm>

int main()
{
    const char* const file_name = "whatever.txt" ;

    std::string text ;

    // read the characters in the file into the string
    // mode: text, input
    {
        std::ifstream file(file_name) ; // default mode is text, input
        char c ;
        while( file.get(c) ) // for each char, including white spaces
            text += c ; // append to string
    }

    // reverse the string
    std::reverse( text.begin(), text.end() ) ;

    // write the reversed string into the file
    // mode: text, output, truncate
    {
        std::ofstream file(file_name) ; // default mode is text, output, truncate
        file << text ;
    }
}
LB: I mentioned the book (click on that link). And if I have misunderstood that hint, what do you understand from it? I'll be happy if you can help me.
That link goes to a 404. And why is JLBorges' post reported??
I don't know about the JLBorges.
For that book google it: Programming Principles and Practice Using C++. Or again click on that link.
Last edited on
I'll be happy if you can help me.

So far you've been given two solutions, and it's been explained that open modes on their own don't help.

You always need to read the data, and write it reversed.
And because C++ doesn't yet support memory mapped files, there's an extra step of reversing the data in memory before writing it (as our examples show).

So how more can anyone help you?
So far you've been given two solutions


And no one of them was like what I said I need to. Though, I'm thankful because of your trying.

it's been explained that open modes on their own don't help.


So why Bjarne wanted it than me? He didn't know they don't help in such an exercise!?

So how more can anyone help you?


I need a simple code which reverses the order of a string using ios_base:: .....

PS: I have wrote this simple code for that problem:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{
	string name1 = "first", name2 = "last", test;
	ifstream ifs(name1.c_str());
	getline(ifs,test);
	ifs.close();

	ofstream ofs(name2.c_str(),ios_base::app);
	 for(int i=test.size()-1; i>=0; i--)
		 ofs << test[i];

	ofs.close();
		return 0;
}


This code works as I want to. But apparently whether we use ,ios_base::app); or not, this code works well!
So existence of ,ios_base::app); is meaningless here!
closed account (Dy7SLyTq)
thats just a messy version of what jlborges did...
Messy or not messy, the problem is not that. The main point here is that apparently using only those file open modes effectively for reversing a text file is not possible and thus the exercise is incorrect!
The exercise is reversing the contents of a file. The exercise has been solved.

You give too much importance to a hint.
The hint was obviously not a suggestion of how to solve the exercise.
Instead it was probably only meant to direct you to a relevant previous chapter.

(Probably) the only solution where an open mode helps (namely std::ios_base::ate) is the solution I wrote about in a previous post (and I'll explain again):

1) you position at the end (last byte) of the input file, read the last byte
2) write the byte to the output file
3) reposition to before-previous byte, read it, write it
4) ... and so on until you reach the first byte in the input file

But the above method is so stupidly convoluted that I am extremely sure it's not what Stroustrup intended you to do.
Last edited on
Wrong.
> 1) you position at the end (last byte) of the input file, read the last byte
> 2) write the byte to the output file
> 3) reposition to before-previous byte, read it, write it
> 4) ... and so on until you reach the first byte in the input file

> But the above method is so stupidly convoluted...

There is no guarantee that the above method (relative seek) will work at all on streams opened in text mode.

Do not use the second member function with text files, because Standard C++ does not support relative seeks in text files. http://msdn.microsoft.com/en-us/library/y2d6fx99.aspx


If the stream is opened in binary mode, no escape sequence translations are performed; we might end up trashing the file by reversing the individual bytes in the byte sequences for, say, new line.


> it's not what Stroustrup intended you to do.

+1
Last edited on
+1 to the above and additionally even if it worked, it would be painfully slow. Most OSes are optimized for sequential reads. Even if you request 1 byte from a file, internally the OS will read a huge chunk like a few kilobytes or maybe even megabytes. Seeks are slow. Seeks are efficient only if you need to skip a really large part of a file (like several MBs, not single bytes).
Pages: 12