1

Im trying to output the console to a text file that can be created/named by the user when asked for what file the use would like to output to, but for some reason it only shows the result in the console. Is there a way to have the output be sent to a new text file INSIDE eclipse? Here's the code I have written.

Code:

import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;

public class Project03 {

    public static void main(String[] args) throws FileNotFoundException {
        CaesarCipher CaesarCipher = new CaesarCipher("", 0);
        Scanner choice = new Scanner(System.in);
        Scanner intoff = new Scanner(System.in);
        Scanner output = new Scanner(System.in);
        System.out.println("Type E to encrypt a file, or D to decrypt a file");
        String pick = choice.nextLine();
        if (pick.toLowerCase().equals("e")) {
            System.out.println("Enter the file path of the text you'd like to encrypt: ");
            File file = new File(choice.nextLine());
            Scanner textfile = new Scanner(file);
            String line = textfile.nextLine();
            System.out.println("Enter the offset you would like to use (must be 1-25)");
            int offset = intoff.nextInt();
            System.out.println("Name the file you would like to output to");
            String TextOutput = output.nextLine();
            System.out.println(CaesarCipher.encode(line, offset));
            PrintStream out = new PrintStream(new FileOutputStream(TextOutput));
            System.setOut(out);
        } else if (pick.toLowerCase().equals("d")) {
            System.out.println("Enter the file path of the text you'd like to decrypt: ");
            File file = new File(choice.nextLine());
            Scanner textfile = new Scanner(file);
            String line = textfile.nextLine();
            System.out.println("Enter the offset you would like to use (must be 1-25)");
            int offset = choice.nextInt();
            System.out.println("Name the file you would like to output to");
            String TextOutput = output.nextLine();
            System.out.println(CaesarCipher.decode(line, offset));
            PrintStream out = new PrintStream(new FileOutputStream(TextOutput));
            System.setOut(out);
        } else {
            System.out.println("Something went Wrong");
        }
    }
}
Doug Barta
  • 161
  • 2
  • 15
  • You'd just need to create the file first and include it in eclipse. – Elipzer Oct 09 '15 at 01:08
  • You know you should set the `System.out` BEFORE you write to it, otherwise it won't re-direct? Also, you should probably use a simple `Writer` or `OutputStream` instead, have a look at [Basic I/O](http://docs.oracle.com/javase/tutorial/essential/io/). You also don't need three `Scanner`s all reading from the SAME input, they will all see the same thing at the same time... – MadProgrammer Oct 09 '15 at 01:08
  • Possible duplicate of http://stackoverflow.com/questions/2850674/where-to-put-a-textfile-i-want-to-use-in-eclipse – Elipzer Oct 09 '15 at 01:09
  • *"Is there a way to have the output be sent to a new text file INSIDE eclipse?"* - I don't think that's really a good idea, what happens if the user enters "C:\MyTextFile.txt"? Then the file should be written to where ever the user directs it. If the user doesn't supply a path, then it will be written to the same location that the program is been executed from. If they provide a path which doesn't exist, then you're in trouble ;) – MadProgrammer Oct 09 '15 at 01:12

2 Answers2

1

Here your working code

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.Scanner;

public class Project03 {

    public static void main(String[] args) throws FileNotFoundException {

        Scanner input = new Scanner(System.in);
        // Don't need to bulk of Scanner object
        System.out.println("Type E to encrypt a file, or D to decrypt a file");
        String pick = input.nextLine();
        if (pick.toLowerCase().equals("e")) {
            System.out
                    .println("Enter the file path of the text you'd like to encrypt: ");
            File file = new File(input.nextLine());
            Scanner inputFromFile = new Scanner(file);
            String line = inputFromFile.nextLine();
            System.out
                    .println("Enter the offset you would like to use (must be 1-25)");
            int offset = input.nextInt();
            input.nextLine(); // Consume Extra NewLine
            System.out.println("Name the file you would like to output to");
            String textOutput = input.nextLine();

            PrintStream out = new PrintStream(new FileOutputStream(textOutput));
            System.setOut(out);

            System.out.println(CaesarCipher.encode(line, offset)); // This line should be placed after System.setOut(out), to redirect output to the file

            inputFromFile.close();

        } else if (pick.toLowerCase().equals("d")) {
            System.out
                    .println("Enter the file path of the text you'd like to decrypt: ");
            File file = new File(input.nextLine());
            Scanner inputFromFile = new Scanner(file);
            String line = inputFromFile.nextLine();
            System.out
                    .println("Enter the offset you would like to use (must be 1-25)");
            int offset = input.nextInt();
            input.nextLine(); // Consume Extra NewLine
            System.out.println("Name the file you would like to output to");
            String textOutput = input.nextLine();

            PrintStream out = new PrintStream(new FileOutputStream(textOutput));
            System.setOut(out);

            System.out.println(CaesarCipher.decode(line, offset));
            inputFromFile.close();

        } else {
            System.out.println("Something went Wrong");
        }
        input.close();

    }
}

Some Suggestion

  1. Follow Naming Rule
  2. For every type of stream use one Scanner object per type.
  3. Static method call in static way.
ashiquzzaman33
  • 5,781
  • 5
  • 31
  • 42
  • Actually, now I take a longer look at the OP's code, your example might not be wrong, but I would highlight the fact that you DIDN'T use `System.setOut(out);` ... might need to wash my eyes out with bleach :P - +1 to you though, that's a much simpler solution then trying to redirect the `stdout` – MadProgrammer Oct 09 '15 at 01:14
  • When the file name is typed in by the user, where exactly does the file go? Can it only work if there is a file path included in it? Also when i tired changing all the scanners to one singular scanner it was throwing a file not found exception, alas your revised code worked.. hm.. – Doug Barta Oct 09 '15 at 01:42
  • @DougBarta If user give only file name then output files goes to your project directory, After refreshing project you can see that. – ashiquzzaman33 Oct 09 '15 at 01:46
  • But if user give full path then output file goes to that directory. If directory is invalid then may be you get .FileNotFoundException. – ashiquzzaman33 Oct 09 '15 at 01:48
  • I think it was because of the lack of .nextLine( ) after the .nextInt( ) that was throwing it off – Doug Barta Oct 09 '15 at 01:51
  • Yes, because `nextInt()` can not consume newline character and that newline feed by next `nextLine.` – ashiquzzaman33 Oct 09 '15 at 01:52
0

for some reason it only shows the result in the console

as @MadProgrammer said, you write to "System.out" before opening the "out" file, therefore, the result can't appear in the file.

System.out.println(CaesarCipher.encode(line, offset));
PrintStream out = new PrintStream(new FileOutputStream(TextOutput));
System.setOut(out);

Do you want something like this:

char[] decoded = CaesarCipher.decode(line, offset);
System.out.println(decoded);
PrintStream out = new PrintStream(new File(TextOutput));
out.print(decoded);
out.close();

Now if you really want to redirect System.out, it is another story that goes like that (but it does the same; you still have to call two "println" one for the file, the other for the console):

import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;

public class Project03 {

    public static class CaesarCipher {

        public CaesarCipher(String string, int i) {
        }

        public char[] encode(String line, int offset) {
            return line.toCharArray();
        }

        public char[] decode(String line, int offset) {
            return line.toCharArray();
        }

    }

    public static class OutStream extends PrintStream {
        PrintStream out;

        public OutStream(File file, PrintStream out) throws FileNotFoundException {
            super(file);
            this.out = out;
        }

        @Override
        public void println(char[] x) {
            super.println(x);
            out.println(x);
        }
    }

    public static void main(String[] args) throws FileNotFoundException {
        CaesarCipher CaesarCipher = new CaesarCipher("", 0);
        Scanner choice = new Scanner(System.in);
        Scanner intoff = new Scanner(System.in);
        Scanner output = new Scanner(System.in);
        System.out.println("Type E to encrypt a file, or D to decrypt a file");
        String pick = choice.nextLine();
        if (pick.toLowerCase().equals("e")) {
            System.out.println("Enter the file path of the text you'd like to encrypt: ");
            File file = new File(choice.nextLine());
            Scanner textfile = new Scanner(file);
            String line = textfile.nextLine();
            System.out.println("Enter the offset you would like to use (must be 1-25)");
            int offset = intoff.nextInt();
            System.out.println("Name the file you would like to output to");
            String TextOutput = output.nextLine();
            OutStream out = new OutStream(new File(TextOutput), System.out);
            System.setOut(out);
            System.out.println(CaesarCipher.encode(line, offset));
        } else if (pick.toLowerCase().equals("d")) {
            System.out.println("Enter the file path of the text you'd like to decrypt: ");
            File file = new File(choice.nextLine());
            Scanner textfile = new Scanner(file);
            String line = textfile.nextLine();
            System.out.println("Enter the offset you would like to use (must be 1-25)");
            int offset = choice.nextInt();
            System.out.println("Name the file you would like to output to");
            String TextOutput = output.nextLine();
            OutStream out = new OutStream(new File(TextOutput), System.out);
            System.setOut(out);
            System.out.println(CaesarCipher.encode(line, offset));
        } else {
            System.out.println("Something went Wrong");
        }
    }
}

If you use more than "println" you will have to overload it in "OutStream". I didn't touch the rest of the code in purpose.

loic.jaouen
  • 489
  • 4
  • 9