While 循环和 BufferedReader

While loop & BufferedReader

我正在为 class 做作业,我在设置用户通过输入 Q 或 q 退出程序时遇到了问题。

我的教授不允许我们使用 Scanner,因为他出于某种原因不喜欢它,而且我以前从未使用过 BufferedReader,我一直有点困惑。此外,他不希望我们提示用户,或者我只是在最后设置一些内容,说按回车键继续或 Q/q 退出。但是我不确定如果没有它该如何处理,有什么建议吗?截至目前,如果我选择使用 q 退出,我会收到错误消息,因为我已将所有输入解析为双精度值。

感谢您的帮助,下面是我的代码。

public class CST200_Lab2 {  

  public static void main(String[] args) throws IOException {
    String inputString = " ";

    double hullSpeed;
    double displacementEqu;
    double sailAreaEqu;
    double capSize;
    double comfortIndex;

    InputStreamReader ISR = new InputStreamReader(System.in);
    BufferedReader BR = new BufferedReader(ISR);

    NumberFormat NF = NumberFormat.getNumberInstance();
    NF.setMaximumFractionDigits(2);
    NF.setMinimumFractionDigits(2);

    while(!(inputString.equalsIgnoreCase("q"))) {

        //Input for the Length of the vessel
        inputString = BR.readLine();
        double lengthVesselDbl = Double.parseDouble(inputString);

        //Input for the water line length for the Vessel
        inputString = BR.readLine();
        double waterLineLengthDbl = Double.parseDouble(inputString);

        //Input for the Beam / width of the vessel
        inputString = BR.readLine();
        double widthVesselDbl = Double.parseDouble(inputString);

        //Input for the displacement
        inputString = BR.readLine();
        double displacementDbl = Double.parseDouble(inputString);

        //Input for the Sail Area
        inputString = BR.readLine();
        double sailAreaDbl = Double.parseDouble(inputString);

        /**EQUATIONS*/
        //Calculate the Hull Speed
        hullSpeed = 1.34 * (Math.pow(waterLineLengthDbl, .5));

        //Calculate Displacement to Waterline Length
        displacementEqu = (displacementDbl / 2240.00) / Math.pow((.01 * waterLineLengthDbl), 3);

        //Calculate Sail Area to Displacement
        sailAreaEqu = sailAreaDbl / Math.pow((displacementDbl / 64.00), .67);

        //Calculate the Capsize index.
        capSize = widthVesselDbl / Math.pow((displacementDbl / 64.00), .33);

        //Calculate the Comfort index
        comfortIndex = (displacementDbl) / (.65*(.7 * waterLineLengthDbl 
                + .3 * lengthVesselDbl) * Math.pow((widthVesselDbl), 1.33));

        //Print out the User input 
        System.out.println("LOA: " + NF.format(lengthVesselDbl));
        System.out.println("LWL: " + NF.format(waterLineLengthDbl));
        System.out.println("BEAM: " + NF.format(displacementDbl));

    };
}
}

****更新****

根据你们中一些人的建议,我仍然遇到问题。该建议的问题是它现在要求 6 个用户输入,而不是程序所需的 5 个。另外,如果你在程序中间退出,你会得到和我之前一样的错误...

Exception in thread "main" java.lang.NumberFormatException: For input string: "Q"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at CST200_Lab2.main(CST200_Lab2.java:38)

************最新更新***************

这就是我现在正在做的事情,而且看起来很有效。这是一条好的路线吗?有没有更好的写法,让用户可以随时输入Q,结束程序?我似乎找不到办法,因为输入被解析为双精度。

while(!(exit.equalsIgnoreCase("q")) && !(exit.equals(null))) {

While 循环结束时

exit = BR.readLine();

不太清楚您要做什么,因为您似乎在 while 循环内多次从控制台读取数据。但是,这将允许循环在用户通过控制台输入 qQ 时终止:

String inputString = "";

//assign the trimmed user input line to inputString and check if it equals q ignoring case
while ((inputString = BR.readLine()) != null && (!inputString.equalsIgnoreCase("q"))) {
       //do stuff with inputString in while loop
}

如果您可以添加更多详细信息,我可以在答案中添加更多内容。

更新

在你在评论中澄清你想要什么之后,我只改变了循环来做你想做的事情,并将变量(你在 while 循环中的)放在外面:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.NumberFormat;

public class CST200_Lab2 {

    public static void main(String[] args) throws Exception {
        String inputString = "";

        double hullSpeed;
        double displacementEqu;
        double sailAreaEqu;
        double capSize;
        double comfortIndex;

        // declare variables outside the loop to be preserved
        // initialize at -1 because length and area can't be negative
        // and because my compiler requires initialization
        double lengthVesselDbl = -1;
        double waterLineLengthDbl = -1;
        double widthVesselDbl = -1;
        double displacementDbl = -1;
        double sailAreaDbl = -1;

        InputStreamReader ISR = new InputStreamReader(System.in);
        BufferedReader BR = new BufferedReader(ISR);

        NumberFormat NF = NumberFormat.getNumberInstance();
        NF.setMaximumFractionDigits(2);
        NF.setMinimumFractionDigits(2);

        System.out.println("Starting program!");

        int i = 1;

        // loop and read input, and assign to proper variable
        while ((inputString = BR.readLine()) != null && (!inputString.equalsIgnoreCase("q"))) {
            try {
                switch (i) {
                case 1:
                    lengthVesselDbl = Double.parseDouble(inputString);
                    break;

                case 2:
                    waterLineLengthDbl = Double.parseDouble(inputString);
                    break;

                case 3:
                    widthVesselDbl = Double.parseDouble(inputString);
                    break;

                case 4:
                    displacementDbl = Double.parseDouble(inputString);
                    break;

                case 5:
                    sailAreaDbl = Double.parseDouble(inputString);
                    break;

                default:
                    System.out.println("Input is not being used. Press Q to exit!");
                    break;
                }
                i++;
            } catch (NumberFormatException e) {
                System.out.println("Please enter a number!");
            }
        }

        // check if variables were assigned properly
        if (lengthVesselDbl >= 0 && waterLineLengthDbl >= 0 && widthVesselDbl >= 0 && displacementDbl >= 0
                && sailAreaDbl >= 0) {

            // Calculate the Hull Speed
            hullSpeed = 1.34 * (Math.pow(waterLineLengthDbl, .5));

            // Calculate Displacement to Waterline Length
            displacementEqu = (displacementDbl / 2240.00) / Math.pow((.01 * waterLineLengthDbl), 3);

            // Calculate Sail Area to Displacement
            sailAreaEqu = sailAreaDbl / Math.pow((displacementDbl / 64.00), .67);

            // Calculate the Capsize index.
            capSize = widthVesselDbl / Math.pow((displacementDbl / 64.00), .33);

            // Calculate the Comfort index
            comfortIndex = (displacementDbl)
                    / (.65 * (.7 * waterLineLengthDbl + .3 * lengthVesselDbl) * Math.pow((widthVesselDbl), 1.33));

            // Print out the User input
            System.out.println("LOA: " + NF.format(lengthVesselDbl));
            System.out.println("LWL: " + NF.format(waterLineLengthDbl));
            System.out.println("BEAM: " + NF.format(displacementDbl));
        } else {
            throw new Exception("Dimensions weren't initialized!");
        }
    }
}

既然你说假设用户知道什么时候输入什么维度或值,我做了 switch 声明,以便根据循环的迭代,将用户输入的值分配给适当的变量,因为每次迭代都会读入用户输入。在第 5 次迭代后,用户提供的输入没有任何反应,一旦用户输入 Q,循环就会终止。

您需要检查流的结尾,并且您正在检查刚刚输入的行之前的行。试试这个:

while ((inputString = BR.readLine()) != null && !inputString.equalsIgnoreCase("q"))

这是和我一起工作的:

while (!(line = scan.readLine()).isEmpty())

对于这个问题,我想这就像你的问题: https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=380