提问人:Chance H 提问时间:8/15/2023 更新时间:8/15/2023 访问量:56
If-statement 布尔逻辑在我的 switch 语句中不起作用
If-statement boolean logic not working within my switch statement
问:
我正在为一个个人项目编写一个函数,并尝试创建一个将文本行居中放在控制台上的函数。我找到了小于一行长的字符串的解决方案,但在使用较大的字符串时遇到了困难。代码行为不稳定,我认为由于我不知道的一些问题,逻辑无法正常工作。我对 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 语句再次运行循环。
答:
你写开关的方式,它“失败了”。下面是一个简单的代码片段,用于演示 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");
}
上面会打印.不仅.54321
5
您需要在每个案例陈述的末尾休息:
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 行为。5
break
但是,有更好的选择;其他形式的开关不会受到这个难题的影响。事实上,现在(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 亿个条目,这显然是不可行的。但是有了块,它现在已经很详尽了。用作表达式的非穷举开关会给出编译器错误,告诉您开关并非详尽。Five
int
default
NB:如果你在想:说,那个失败的东西,那是非常愚蠢的!是的,可能。Java v1.0 向后弯腰,在语法上看起来尽可能接近 C,因为 C 在当时 Java 想要流行的环境中绝对占主导地位。这解释了大量“他们在想什么”的语法选择(而 C 本身也同样“植根于历史的迷雾”对他们的选择进行了解释,等等,直到你是印第安纳琼斯在 1950 年代进行洞穴探险,弄清楚为什么事情会变成现在这样。不过,有趣的爱好)。不要敲它 - 它奏效了。Java 在发布后的大约十年内比 C 更受欢迎,现在仍然如此。
评论
break
case
break
} while (set = false);
是作业,不是比较