如何将输入输入到java程序中,但输出仍显示在输出中?

时间:2016-12-14 16:27:07

标签: java linux shell unix

假设我有一个使用扫描仪要求三个数字的程序,如下所示:

Scanner console = new Scanner(System.in);
int[] numbers = new int[3];
System.out.println("Hello!");
for (int i = 0; i<3; i++){
    System.out.print("Please enter a number: ");
    numbers[i] = console.nextInt();
}

我想通过重定向一些输入来测试这样的程序,然后将输出重定向到文件。

input.txt中

3
4
5

命令

java program < input.txt > output.txt

问题是output.txt看起来像这样

Hello!
Please enter a number: Please enter a number: Please enter a number: 

与此相反

Hello!
Please enter a number: 3
Please enter a number: 4
Please enter a number: 5

有没有办法让output.txt看起来更像第二个?我在Mac上,如果这改变了什么。

我不想修改代码 - 我必须为很多类似的程序运行此测试。

3 个答案:

答案 0 :(得分:2)

为什么您的程序无法按预期工作

在输出中,字符串“Please enter a number:”被链接而没有换行符,因为您没有在程序中打印换行符。当程序以交互模式运行时,用户将进入换行符。

输出文件中没有数字,因为您的程序不会将它们打印到标准输出。同样,当程序以交互模式运行时,用户输入数字,但不输入程序。在重定向输出的情况下,来自输入文件的数字由程序读取,但从不打印到标准输出。

正确的方法

您应该检查程序是否以交互模式运行(从TTY读取输入时)。

测试/ MyApp.java

package test;

import java.util.Scanner;
import java.io.Console;

class MyApp {
    public static void main(String args[]) {
        Scanner scanner = new Scanner(System.in);
        Console console = System.console();

        int[] numbers = new int[3];
        for (int i = 0; i < 3; i++){
            if (console != null) {
                System.out.print("Please enter a number: ");
            }
            numbers[i] = scanner.nextInt();
            System.out.printf("Number: %d\n", numbers[i]);
        }
    }
}

测试

$ printf '%d\n%d\n%d\n' 1 2 3 > file
$ javac -cp . test/MyApp.java
$ java -cp . test/MyApp < file > out
$ cat out
Number: 1
Number: 2
Number: 3

答案 1 :(得分:1)

您可以采取哪些措施来获得输入和输出的混合值:

1)创建自己的应用程序,它将调用应用程序的main方法进行测试(假设所有应用程序具有相同的包和主类名称,或者您必须将此信息提供给您自己的程序,并使用反射来调用其他程序。)

您的应用程序将执行以下步骤:

2)存储常规系统InputStream

InputStream oldInputStream = System.in;

3)创建自己的InputStream子类(让我们称之为YourCustomInputStream),并实现不同的读取方法,打印从System.inSystem.out的内容,并且还返回值。

例如:

@Override
public int read(){

    int readInt = oldInputStream.read();
    System.out.println(readInt);
    return readInt;

}

4)用你自己的信息流替换系统的输入:

 System.setIn(new YourCustomInputStream());

5)调用应用程序的main方法进行测试。

答案 2 :(得分:0)

首先,我想像这样合并stdout和stderr:

while read -r num; do
   sleep 1
   echo ${num}>&2
   echo ${num}
done < input.txt | java program

如果要将结果重定向到文件,则会失败。

那么你可以尝试下一个结构:

while read -r num; do
   sleep 1
   echo ${num}
done < input.txt| tee -a output.txt| java program >> output.txt