简体   繁体   English

如何使用“Enter”键退出无限循环?

[英]How to exit infinite loop using “Enter” key?

So, I'm trying to exit the infinite loop using the "Enter" key, and I'm kind of stuck.所以,我试图使用“Enter”键退出无限循环,但我有点卡住了。 Can someone please help me to see where I'm going wrong?有人可以帮我看看我哪里出错了吗? Would be highly appreciated.将不胜感激。 Or even a better way to do it.或者甚至有更好的方法来做到这一点。 I just want to make this a learning experience我只是想让这成为一种学习体验

import java.util.Scanner;导入 java.util.Scanner;

class Main {类主要{

public static void main(String[] args) {公共静态无效主(字符串 [] args){

System.out.println("Please enter a DNA sequence: ");

Scanner read = new Scanner(System. in );
String reverse = "";

while (true) {
  String input = read.next();

  StringBuilder DnaString = new StringBuilder();
  for (int i = input.length() - 1; i >= 0; i--) {
    reverse = reverse + input.charAt(i);
  }
  for (char c: input.toCharArray()) {
    switch (c) {
    case 'A':
      DnaString.append('T');
      break;
    case 'T':
      DnaString.append('A');
      break;
    case 'G':
      DnaString.append('C');
      break;
    case 'C':
      DnaString.append('G');
      break;
    default:
      DnaString.append(".");
      break;
    case '\u0000':
      return;
    }
  }
  System.out.println("Reversed DNA sequence =");
  System.out.println(DnaString + "");
  System.out.println("Enter a next DNA sequence (Press ___ to exit) : ");

}

} } } }

Scanner is a thing that will take any stream of textual input (characters) and chop it into distinct pieces.扫描仪是一种可以获取任何文本输入(字符)流并将其切割成不同部分的东西。

It knows how to lop things into pieces by looking for the so-called delimiter pattern .它知道如何通过寻找所谓的定界符模式将事物分成几部分。 All the things in between any 2 delimiter patterns are called tokens .任何 2 个分隔符模式之间的所有内容都称为标记 The delimiter bits are tossed away, and only the tokens are returned.分隔符位被丢弃,只返回令牌。 Thus, a scanner breaks down any input into a sequence of token - delimiter - token - delimeter - token - delimiter - and so on, tossing away the delimiters, and giving you the tokens.因此,扫描器将任何输入分解为一系列标记 - 分隔符 - 标记 - 分隔符 - 标记 - 分隔符 - 等等,丢弃分隔符,并为您提供标记。 Optionally, by calling eg .nextInt() , you're asking it to also interpret the token in a specific way.或者,通过调用例如.nextInt() ,您要求它也以特定方式解释令牌。 But the token/delimiter/token flow is just how it works;但是令牌/分隔符/令牌流就是它的工作原理; .nextInt() will not magically work out if you enter '123hello' - that will crash, because '123hello' will be the token first, and the Int part only kicks in after that, and asks to treat that token as an int, which won't work, as it isn't an int.如果您输入 '123hello',. .nextInt()将不会神奇地工作 - 这将崩溃,因为 '123hello' 将首先成为令牌,而Int部分仅在此之后启动,并要求将该令牌视为 int,这是行不通的,因为它不是整数。 nextInt is just convenience for Integer.parseInt(next()) , that is all. nextInt只是方便Integer.parseInt(next()) ,仅此Integer.parseInt(next())

So, all you really want is to read that newline, or rather blank input, as a token.因此,您真正想要的只是读取该换行符,或者更确切地说是空白输入,作为标记。

But, by default, that is impossible : The delimiter pattern for a newly created scanner (so, including the one you made here) is "\\\\s+" .但是,默认情况下,这是不可能的:新创建的扫描仪(因此,包括您在此处制作的扫描仪)的分隔符模式"\\\\s+" This is a regular expression that means: "1 or more characters, all of which count as whitespace as per the unicode specification".这是一个正则表达式,意思是:“1 个或多个字符,根据 unicode 规范,所有这些字符都算作空格”。 Enter is whitespace.输入是空格。 So is tab, space, and a bevy of more exotic characters like the non-breaking space.制表符、空格和一系列更奇特的字符(如不间断空格)也是如此。

A single newline, and multiple newlines, are all just a single delimiter to a scanner .单个换行符和多个换行符都只是扫描仪的单个分隔符 It is therefore impossible to do what you want with a default-configured scanner - all characters that are part of the delimiter are tossed, so you need the input to move from 'part of a delimiter' to 'part of a token' and back again in order to see anything with your .next() calls.因此,使用默认配置的扫描仪无法执行您想要的操作 - 作为分隔符一部分的所有字符都被丢弃,因此您需要将输入从“分隔符的一部分”移动到“令牌的一部分”并返回再次查看您的.next()调用的任何内容。

There are 2 solutions to this.对此有 2 种解决方案。 The commonly advised but stupid solution, and the less commonly advised, correct solution.通常建议但愚蠢的解决方案,以及不太常建议的正确解决方案。

  • The right way: "\\\\s+" is a bad default.正确的方法: "\\\\s+"是一个糟糕的默认值。 What you usually want is for the delimiter to be a single newline , and not 'any amount of whitespace'.您通常想要的是分隔符是单个换行符,而不是“任何数量的空格”。 This way, to read entire names (with spaces in them), just call .next() .这样,要读取整个名称(其中包含空格),只需调用.next() Each and every enter press separates 1 token.每次输入按分隔 1 个标记。 Now, if you press enter more than once, you just get a bunch of blank-string tokens back, which you can read with eg next(). It will return a blank string. To do that, immediately after invoking现在,如果你多次按下回车键,你只会得到一堆空白字符串标记,你可以用例如next(). It will return a blank string. To do that, immediately after invoking来读取它们next(). It will return a blank string. To do that, immediately after invoking next(). It will return a blank string. To do that, immediately after invoking next(). It will return a blank string. To do that, immediately after invoking new Scanner , invoke: scanner.useDelimiter("\\r?\\n")`. next(). It will return a blank string. To do that, immediately after invoking new Scanner next(). It will return a blank string. To do that, immediately after invoking , invoke: scanner.useDelimiter("\\r?\\n")`。 This pattern represents a newline on either windows or unix.此模式表示 windows 或 unix 上的换行符。

  • The bad way (I explain it here because you're going to hear this advice, so I best explain why it is bad advice, given that it is so common!): Use nextLine() .不好的方式(我在这里解释它是因为你会听到这个建议,所以我最好解释为什么它是不好的建议,因为它很常见!):使用nextLine() This foregoes the delimiter/token concept entirely, but it does not work well with any other method in scanner.这完全放弃了分隔符/令牌概念,但它不适用于扫描仪中的任何其他方法。 For example, if you invoke nextInt() to read an integer and then nextLine() to read somebody's full name, it doesn't work, because nextLine() will actually return all characters starting at the first character of the delimiter (eg after the last character of the previous token) that caused the last next() method to return, all the way to the newline.例如,如果您调用nextInt()读取一个整数,然后nextLine()读取某人的全名,则它不起作用,因为nextLine()实际上将返回从分隔符的第一个字符开始的所有字符(例如前一个标记的最后一个字符)导致最后next()方法返回,一直到换行符。 So, assuming the user hits their age, hits enter, and types their name, That nextLine() call returns nothing: It returns the characters between the end of that integer, and the next newline, which is blank.因此,假设用户点击他们的年龄,点击 Enter 并输入他们的名字,那么nextLine()调用将不返回任何内容:它返回该整数末尾和下一个空白的换行符之间的字符。 That's why it is a bad idea that is fragile and weird.这就是为什么它是一个脆弱而奇怪的坏主意。 Don't do this.不要这样做。

All you then have to do to fix your code, is realize that after String input = read.next() , input will be blank;然后你需要做的就是修复你的代码,意识到在String input = read.next()input将是空白的; eg input.isEmpty() will be true, input.length() will return 0, and input.equals("") will be true.例如input.isEmpty()将为真, input.length()将返回 0,而input.equals("")将为真。 You can then exit the while construct, eg with a break statement.然后您可以退出while构造,例如使用break语句。 Or straight up System.exit(0);或者直接System.exit(0); - whichever you feel is best. - 你觉得哪个最好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM