If-statement 布尔逻辑在我的 switch 语句中不起作用

If-statement boolean logic not working within my switch statement

提问人:Chance H 提问时间:8/15/2023 更新时间:8/15/2023 访问量:56

问:

我正在为一个个人项目编写一个函数,并尝试创建一个将文本行居中放在控制台上的函数。我找到了小于一行长的字符串的解决方案,但在使用较大的字符串时遇到了困难。代码行为不稳定,我认为由于我不知道的一些问题,逻辑无法正常工作。我对 switch 语句没有太多经验,但认为这是边做边学的好时机。因此,如果答案很明显,请不要生气。

为了解释代码,我输入了一个 String 单词,我想将其拆分为 2 个较小的 String,这些字符串以 200(全屏)字符宽的控制台为中心(稍后可能会放大以允许更多行)。我的想法是,在分线的位置上有三个偏好:句点、逗号,最后是空格。我正在尝试使用一个 do-while 循环按顺序尝试每个首选项,并在 175 到 200 个字符之间找到一个可接受的拆分点。我在 splitWords(String words) 函数内部的所有问题,但我包含了调用它以实现整体性的函数。

这是编写的代码:

public static void printCenter(String words){ //assumes a 200 character wide console

        int x = words.length();
        int y = (200-x);
        int z= y/2;

        if(x<175){ //no need for formatting second line
            for(int i=z; i>0; i--){
                System.out.print(" ");
            }
                System.out.print(words);
            for(int i=z; i>0; i--){
                System.out.print(" ");
            }
            System.out.println("");
        }
        if(x>=175){
            String[] split = splitWords(words);
            String words1 = split[0];
            String words2 = split[1];

            int x1 = words1.length();
            int x2 = words2.length();
            int y1 = (200-x1);
            int y2 = (200-x2);
            int z1= y1/2;
            int z2= y2/2;

            System.out.println("Split at: " + x1 + "\t Output below");
            System.out.println("");

            for(int i=z1; i>0; i--){
                System.out.print(" ");
            }
                System.out.print(words1);
            for(int i=z1; i>0; i--){
                System.out.print(" ");
            }
            for(int i=z2; i>0; i--){
                System.out.print(" ");
            }
                System.out.print(words2);
            for(int i=z2; i>0; i--){
                System.out.print(" ");
            }
            System.out.println("");
        }

    }
public static String[] splitWords(String words){
    String line1 = "";
    String line2 = "";
    int splithere = 0;
    //strings used to create new substrings
    String firstpref = ". ";
    String secondpref = ", ";
    String lastpref = " ";
    int tries = 0;
    boolean set = false;
    System.out.println("started");
    do{
        switch(tries){
            case 0:
                int num = words.indexOf(firstpref,175);
                if(num<200){
                    System.out.print("this should be less than 200: " + num);
                    splithere = words.indexOf(firstpref,175);
                    set=true;
                    System.out.println("found valid split during pass: " + tries + " at: " + splithere);
                }
            case 1:
                if(words.indexOf(secondpref,175)<200){
                    splithere = words.indexOf(firstpref,175);
                    set=true;
                    System.out.println("found valid split during pass: " + tries + " at: " + splithere);
                }
            case 2:
                if(words.indexOf(lastpref,175)<200){
                    splithere = words.indexOf(firstpref,175);
                    set=true;
                    System.out.println("found valid split during pass: " + tries + " at: " + splithere);
                }
        }
        tries++;
    }while(set = false);

    line1 = words.substring(0,splithere);
    line2 = words.substring(splithere,words.length());
    String[] output = {line1,line2};
    System.out.println(" ended with boolean = " + set);
    return output;
    }

下面是 347 个字符字符串的示例输出:

开始 在传递期间找到有效的拆分:0 在:235 以 boolean = false 结尾 拆分位置:235 输出如下:

你在镇中心的一个路口。在西边,穿过一个岗哨,是村庄的中心,受到保护和高度守卫,这个地区是政治家、伟大的抄写员和猎人的家园,最重要的是,酋长的栖息处(这里是弦裂)。向北延伸的旧土路以 T 形结束,一条装饰精美的石路向东延伸。

从我的代码中可以看出,我尝试插入消息来帮助我诊断问题。在我看来,即使 If 语句关闭,开关内的 If 语句也在运行它的一些代码。您还能如何解释控制台打印出“在传递 0 期间找到有效拆分:235”,而该字符串不应具有由 If 语句中的布尔逻辑定义的大于 200 的数字。

另一个 vexxing 问题是 do-while 循环在 set=false 时结束。您可以在控制台上的输出文本中看到这一点。我不明白为什么它不增加 tries++ 并使用新的 switch 语句再次运行循环。

java if-statement 语法错误 do-while 用户体验

评论

3赞 Luatic 8/15/2023
您需要在每个 之后放置,否则它将失败并执行其他情况。这是一个常见的错误,特别是因为某些语言有其他约定,它们会隐含地(IMO 更理智的行为)。breakcasebreak
2赞 MadProgrammer 8/15/2023
} while (set = false);是作业,不是比较
0赞 Chance H 8/15/2023
谢谢!你们俩很到位,现在看起来很棒。感谢您的帮助!
0赞 Gavin 8/15/2023
这不是一个解决方案,但是在“Marco Codes”YouTube 频道上有一个系列,Marco 用 Java 构建了一个文本编辑器。这很有趣

答:

1赞 rzwitserloot 8/15/2023 #1

你写开关的方式,它“失败了”。下面是一个简单的代码片段,用于演示 fall-through 的工作原理:

int x = 5;
switch (x) {
case 5: System.out.print("5");
case 4: System.out.print("4");
case 3: System.out.print("3");
case 2: System.out.print("2");
case 1: System.out.print("1");
}

上面会打印.不仅.543215

您需要在每个案例陈述的末尾休息:

int x = 5;
switch (x) {
case 5: System.out.print("5"); break;
case 4: System.out.print("4"); break;
case 3: System.out.print("3"); break;
case 2: System.out.print("2"); break;
case 1: System.out.print("1"); break;
}

现在它只会打印.许多 Java linting 工具,包括 IDE,都可以配置为要求这样做(如果你没有在每个案例块的末尾写一个代码,它们会将你的代码标记为有问题),或者可能在某个地方写一个带有“fallthrough”一词的注释,以表明你想要 fallthrough 行为。5break

但是,有更好的选择;其他形式的开关不会受到这个难题的影响。事实上,现在(JDK17+)的开关相当灵活。使用箭头表示法,案例块不再落空:

int x = 5;
switch (x) {
case 5 -> System.out.print("5");
case 4 -> System.out.print("4");
case 3 -> System.out.print("3");
case 2 -> System.out.print("2");
case 1 -> System.out.print("1");
}

现在它只打印.5

您也可以将开关编写为表达式:

int x = 5;
String wordified = switch(x) {
  case 5 -> "Five";
  case 4 -> "Four";
  case 3,2,1 -> "Low";
  default -> "Who knows";
};

System.out.println(wordified);

指纹。在这种模式下,您的案例必须“详尽无遗”(涵盖输入类型可能具有的每个值。这需要大约 40 亿个条目,这显然是不可行的。但是有了块,它现在已经很详尽了。用作表达式的非穷举开关会给出编译器错误,告诉您开关并非详尽。Fiveintdefault

NB:如果你在想:说,那个失败的东西,那是非常愚蠢的!是的,可能。Java v1.0 向后弯腰,在语法上看起来尽可能接近 C,因为 C 在当时 Java 想要流行的环境中绝对占主导地位。这解释了大量“他们在想什么”的语法选择(而 C 本身也同样“植根于历史的迷雾”对他们的选择进行了解释,等等,直到你是印第安纳琼斯在 1950 年代进行洞穴探险,弄清楚为什么事情会变成现在这样。不过,有趣的爱好)。不要敲它 - 它奏效了。Java 在发布后的大约十年内比 C 更受欢迎,现在仍然如此。

评论

0赞 Gavin 8/15/2023
我一直认为失败的事情部分是为了帮助保持编译器更简单/更小。少一个规则和一个开关块的行为与任何其他代码块一样。失败可能很有用,但它可能会导致错误,因此应记录其使用。对于 C 语言中开关的“疯狂”使用,请查看“Duff's Device”