我正在为个人项目编写一个函数,并尝试创建一个将文本行置于控制台中心的函数。我找到了一个针对长度小于一行的字符串的解决方案,但在处理较大的字符串时遇到了困难。代码行为不稳定,我认为由于某些我未知的问题,逻辑无法正常工作。我对 switch 语句没有太多经验,但我认为现在是边做边学的好时机。所以,如果答案很明显,请不要生气。
为了解释代码,我输入了一个字符串单词,我想将其拆分为 2 个较小的字符串,这些字符串以 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 at:235 以 boolean = false 结尾 分割于:235 输出如下:
您正处于市中心的十字路口。向西,穿过一个哨所,就是村庄的中心,受到保护和高度戒备,这个地区是政客、伟大的文士和猎人的家园,最重要的是,这里是酋长的栖息地(绳子在这里裂开)。向北延伸的旧土路以 T 形结束,向东延伸出一条装饰精美的石路。
您可以从我的代码中看到我尝试插入消息来帮助我诊断问题。在我看来,即使 If 语句关闭,开关内的 If 语句也会运行它的一些代码。当该字符串永远不应该有大于 200 的数字(如 If 语句中的布尔逻辑所定义)时,您还能如何解释控制台打印出“在第 0 遍过程中找到有效分割:235”。
另一个令人烦恼的问题是 do-while 循环在 set=false 时结束。您可以在控制台的输出文本中看到这一点。我不明白为什么它不增加 attempts++ 并使用新的 switch 语句再次运行循环。
您编写开关的方式,它“失败了”。这是一个简单的片段,展示了失败是如何工作的:
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
。
您需要在每个案例陈述的末尾休息一下。
还有其他形式的开关不会遇到这个难题。事实上,现在(JDK17+)切换相当灵活。使用箭头符号,case 块不再会失败:
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);
打印
Five
。在这种模式下,您的案例必须“详尽”(涵盖输入类型可能具有的每个值。对于int
,这将需要大约 40 亿个条目,显然不可行。但是使用 default
块,它现在是详尽的.用作表达式的非详尽开关会给您一个编译器错误,告诉您您的开关并不详尽。