How to Read a File, Reverse the Order, and Write Reverse Order

How to read a file, reverse the order, and write reverse order

i am not so sure about your environment, and how long the text might be. and i am also not so sure why you need a scanner?

anyway, here's my take on the problem, hope this helps you :)

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.io.Reader;


public class Reverse {

public static void main(String[] args) {

FileInputStream fis = null;
RandomAccessFile raf = null;

// by default, let's use utf-8
String characterEncoding = "utf-8";

// but if you pass an optional 3rd parameter, we use that
if(args.length==3) {
characterEncoding = args[2];
}

try{

// input file
File in = new File(args[0]);
fis = new FileInputStream(in);

// a reader, because it respects character encoding etc
Reader r = new InputStreamReader(fis,characterEncoding);

// an outputfile
File out = new File(args[1]);

// and a random access file of the same size as the input, so we can write in reverse order
raf = new RandomAccessFile(out, "rw");
raf.setLength(in.length());

// a buffer for the chars we want to read
char[] buff = new char[1];

// keep track of the current position (we're going backwards, so we start at the end)
long position = in.length();

// Reader.read will return -1 when it reached the end.
while((r.read(buff))>-1) {

// turn the character into bytes according to the character encoding
Character c = buff[0];
String s = c+"";
byte[] bBuff = s.getBytes(characterEncoding);

// go to the proper position in the random access file
position = position-bBuff.length;
raf.seek(position);

// write one or more bytes for the character
raf.write(bBuff);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// clean up
try {
fis.close();
} catch (Exception e2) {
}
try {
raf.close();
} catch (Exception e2) {
}
}


}


}

How to reverse order numbers in a text file then write the reversed numbers back into the text file

Alright, to read a sequence of numbers and then write them back out in reverse order, you simply need to read the values into an array, keeping track of how many you read, close the file opened for reading, reopen the file for writing, then write the values back out to the file in reverse order.

We will leave reading an unknown number of values from the file and dynamically allocating storage for another day. We will presume for now that you have less than 256 values to read (adjust as necessary). Avoid using magic-numbers in your code, so if you need a constant to size your array, #define one (or more),

#include <stdio.h>

#define MAXI 256 /* if you need a constant, #define one (or more) */

Now declare your array, declare a counter, and since you also do not hardcode filenames, pass the filename to open as the first argument to your program (or read from stdin by default if no argument is given):

int main (int argc, char **argv) {

int arr[MAXI] = {0}; /* array for storing values */
size_t n = 0; /* counter for number stored */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}

Now since you have a fixed array, you cannot read more integer values that you have array elements to hold -- so always protect your array bounds when filling your array. With your file open for reading, all you need to do is read the integers from the file, and close the file after either filling all elements in your array, or reaching the end of file (EOF). Close the file you have open for reading when done:

    /* protect your array bounds, and read/validate 1 int per iteration */
while (n < MAXI && fscanf (fp, "%d", &arr[n]) == 1)
n++; /* on success, increment counter */

if (fp != stdin) /* close file if not stdin */
fclose (fp);

To write the values in reverse order, simply open your file for writing (which will truncate your file). Here you can write to stdout by default if no filename was given. Then loop from your last array element (n - 1) to zero writing each element to your file in reverse order. Close the file when done, but always validate the close after writing to detect any stream errors that may occur that are not otherwise reported:

    /* open file for writing (stdout by default) */
fp = argc > 1 ? fopen (argv[1], "w") : stdout;

if (!fp) { /* validate file open for writing */
perror ("file open failed");
return 1;
}

while (n--) /* write array in reverse order to file */
fprintf (fp, "%d\n", arr[n]);

if (fp != stdout) /* close file if not stdout */
if (fclose(fp) == -1) /* always validate close-after-write */
perror ("fclose-fp");
}

That's it. The full code above would be:

#include <stdio.h>

#define MAXI 256 /* if you need a constant, #define one (or more) */

int main (int argc, char **argv) {

int arr[MAXI] = {0}; /* array for storing values */
size_t n = 0; /* counter for number stored */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}

/* protect your array bounds, and read/validate 1 int per iteration */
while (n < MAXI && fscanf (fp, "%d", &arr[n]) == 1)
n++; /* on success, increment counter */

if (fp != stdin) /* close file if not stdin */
fclose (fp);

/* open file for writing (stdout by default) */
fp = argc > 1 ? fopen (argv[1], "w") : stdout;

if (!fp) { /* validate file open for writing */
perror ("file open failed");
return 1;
}

while (n--) /* write array in reverse order to file */
fprintf (fp, "%d\n", arr[n]);

if (fp != stdout) /* close file if not stdout */
if (fclose(fp) == -1) /* always validate close-after-write */
perror ("fclose-fp");
}

(note: since you didn't provide an example of your input file, a newline separated set of integers was assumed. Adjust the output format as needed)

Example Input File

$ cat dat/10intordered.txt
1
2
3
4
5
6
7
8
9
10

Example Use/Output

Reading stdin wrting to stdout (just pass your filename as 1st argument to read/write to a file),

$ ./bin/revfile < dat/10intordered.txt
10
9
8
7
6
5
4
3
2
1

Look things over and let me know if you have further questions.

Edit Removing Shortcuts & Adding Program Progress Output

With a few edits we can remove the size_t and the shortcut while(n--) loop to make things look more traditional using int and a for loop in reverse order for the second loop. We also added progress messages for both reading and writing. I used an actual file to the information is read and written back to a file to not clutter the program progress notes with the array being written in between:

#include <stdio.h>

#define MAXI 256 /* if you need a constant, #define one (or more) */

int main (int argc, char **argv) {

int arr[MAXI] = {0}; /* array for storing values */
int n = 0; /* counter for number stored */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}

puts ("reading file:");
/* protect your array bounds, and read/validate 1 int per iteration */
while (n < MAXI && fscanf (fp, "%d", &arr[n]) == 1) {
printf (" arr[%3d] : %d\n", n, arr[n]);
n++; /* on success, increment counter */
}
printf ("read of %d integers -- complete.\n", n);

if (fp != stdin) /* close file if not stdin */
fclose (fp);

/* open file for writing (stdout by default) */
fp = argc > 1 ? fopen (argv[1], "w") : stdout;

if (!fp) { /* validate file open for writing */
perror ("file open failed");
return 1;
}

puts ("\nwriting values to file:");
/* loop writing indexes out from n-1 to 0 */
for (int i = n-1; i >= 0; i--) {
printf (" arr[%3d] : %d\n", i, arr[i]);
fprintf (fp, "%d\n", arr[i]);
}
printf ("write of %d integers -- complete.\n", n);

if (fp != stdout) /* close file if not stdout */
if (fclose(fp) == -1) /* always validate close-after-write */
perror ("fclose-fp");
}

Example Input File

$ cat dat/10i.txt
1
2
3
4
5
6
7
8
9
10

Example Use/Output

$./bin/revfile2 dat/10i.txt
reading file:
arr[ 0] : 1
arr[ 1] : 2
arr[ 2] : 3
arr[ 3] : 4
arr[ 4] : 5
arr[ 5] : 6
arr[ 6] : 7
arr[ 7] : 8
arr[ 8] : 9
arr[ 9] : 10
read of 10 integers -- complete.

writing values to file:
arr[ 9] : 10
arr[ 8] : 9
arr[ 7] : 8
arr[ 6] : 7
arr[ 5] : 6
arr[ 4] : 5
arr[ 3] : 4
arr[ 2] : 3
arr[ 1] : 2
arr[ 0] : 1
write of 10 integers -- complete.

Updated File

$ cat dat/10i.txt
10
9
8
7
6
5
4
3
2
1

See if that may not help a bit more and let me know if you are still confused on any areas.

How to read a file in reverse order using C++

Yes, but you basically have to do it manually.

The basic algorithm is as follows:

  1. Seek to the end of the file with is.seekg(0, is.end)
  2. Determine the file size with is.tellg()
  3. Repeatedly seek backwards and read chunks of the file until you reach the front

How to read file from end to start (in reverse order) in Java?

As far as I understand, you try to read backwards line by line.
Suppose this is the file you try to read:

line1

line2

line3

And you want to write it to the output stream of the servlet as follows:

line3

line2

line1

Following code might be helpful in this case:

    List<String> tmp = new ArrayList<String>();

do {
ch = br.readLine();
tmp.add(ch);
out.print(ch+"<br/>");
} while (ch != null);

for(int i=tmp.size()-1;i>=0;i--) {
out.print(tmp.get(i)+"<br/>");
}

Is there a way to reverse the order of lines within a text file using a function in python?

I think the bug you're referring to is in this function:

def reverse_word(line):
data = line.read()
data_1 = data[::-1]
print(data_1)
return data_1

You don't need to call read() on line because it's already a string; read() is called on file objects in order to turn them into strings. Just do:

def reverse_line(line):
return line[::-1]

and it will reverse the entire line.

If you wanted to reverse the individual words in the line, while keeping them in the same order within the line (e.g. turn "the cat sat on a hat" to "eht tac tas no a tah"), that'd be something like:

def reverse_words(line):
return ' '.join(word[::-1] for word in line.split())

If you wanted to reverse the order of the words but not the words themselves (e.g. turn "the cat sat on a hat" to "hat a on sat cat the"), that would be:

def reverse_word_order(line):
return ' '.join(line.split()[::-1])

C++ Outputting a text file in reverse order

Simple to do; just read the entire file into a std::string, then iterate over the string in reverse order (from rbegin() to rend()) and print each character as you go along.

How do I correctly read words from a text file and reverse the order of even words?

You just need to add to std::reverse to your code. I have also reviewed your code fragment.

Your code will look something like this after that:

#include <iostream>
#include <string>
// #include <string.h> -- no need of this header
#include <cstdlib> // not required at all for this code segment, maybe required in your actual code
#include <fstream>
#include <algorithm> // this is additional header that you need

using namespace std; // this is not a good practice though

int main()
{
string word;
ifstream f("text.txt"); // it is not recommended to use single letter variable names
if (f.is_open()) // just keeping f instead of f.is_open() will work the same way
{
while (f >> word)
{
if (word.length() % 2 == 0)
cout << reverse(word.begin(), word.end()) << endl; // using std::reverse here
}
f.close(); // not necessary statement but considered a good practice to prevent memory leaks and access locks.
}
else
cout << "file is not open" << '\n'; // prefer using std::cerr instead of std::cout to log errors
// and better error message will be "Unable to open text.txt!".
return 0; // return something other than 0 in case of error
}

How do I reverse the order of characters in a text file in C++?

Your input file is likely encoded in a multi-byte charset. It does not appear to be UTF-8, though, as is encoded in UTF-8 as bytes E2 80 94, which is — when interpreted in Latin-1, and is encoded in UTF-8 as bytes E2 80 99, which is ’ when interpreted in Latin-1. That is not what you are seeing in your output, though. But the symptom is similar. You are reversing the encoded chars in the string as-is, which will not work for a multi-byte encoding.

To properly reverse a multi-byte encoded string, you would have to know the encoding beforehand and walk through the string based on that encoding, extracting each whole sequence of encoded units and saving each whole unit as-is to the output, rather than reading and saving the individual chars as-is. std::reverse() can't help you with that, unless you use iterators that know how to read and write those whole units.

If you know the encoding beforehand, you may have better luck using std::wifstream/std::wofstream instead, where they are imbue()'ed with a suitable std::locale for the encoding. Then use std::wstring instead of std::string. However, on Windows at least, where std::wstring uses UTF-16, you still have the issue of dealing with multi-unit sequences (though less frequently, unless you are dealing with Eastern Asian languages). So you may have to convert the decoded UTF-16 input to UTF-32 before doing the reversing (then you have to deal with multi-codepoint grapheme clusters), then convert the UTF-32 to UTF-16 before then saving it encoded to the output file.

Also, if you are going to handle the individual chars as-is, to ensure the raw chars are read and written correctly, you should open the files in binary mode, and use UNformatted input/output operations (ie, no operator>> or operator<<):

ifstream ifs(name, std::ios::binary);
if (!ifs) throw runtime_error("Couldn't open input file.");

ofstream ofs("output.txt", std::ios::binary);
if (!ofs) throw runtime_error("Couldn't open output file.");

// Note: there are easier ways to read a file into a std::string!
// See: https://stackoverflow.com/questions/116038/
string s;
for(char ch; ifs.get(ch);)
s.push_back(ch);

reverse(s.begin(), s.end());

for(char ch: s)
ofs.put(ch);
// alternatively:
// ofs.write(s.c_str(), s.size());


Related Topics



Leave a reply



Submit