从扫描仪中获取一个字符输入

142

我正在尝试找到一种从键盘输入 char 的方法。

我尝试使用:

Scanner reader = new Scanner(System.in);
char c = reader.nextChar();

这个方法不存在。

我尝试将c作为String。然而,在每种情况下它并不总是起作用,因为我从我的方法中调用的另一个方法需要一个char作为输入。因此,我必须找到一种明确地以字符形式作为输入的方法。

有什么帮助吗?

24个回答

184

你可以从Scanner.next中获取第一个字符:

char c = reader.next().charAt(0);

要仅消耗一个字符,您可以使用:

char c = reader.findInLine(".").charAt(0);

要严格地消耗一个字符,你可以使用:

char c = reader.next(".").charAt(0);

7
实际上它涉及多个字符,但只对第一个字符进行操作。 - Ralph
3
要仅使用字符,请使用 char c = reader.next("[a-zA-Z]").charAt(0); 的方式来消耗 @user1804697。 - Reimeus
17
在这个语境中,“exactly”和“strictly”的区别是什么? 在这个语境中,“exactly”表示完全符合要求,而“strictly”则强调了遵守规定或标准的程度。 - user6096242
2
@Reimeus,复制粘贴代码然后运行它到底有什么价值? - bharal
3
下一个版本的 next() 在输入 bhjgfbergq35987t%$#%$# 这种无意义的字符时会崩溃,而 findInLine() 不会。我的问题实际上更多地涉及到 "strictly" 和 "exactly" 这两个单词,而不是相应的代码片段。我不知道在什么情况下这些词不是同义词。 - user6096242
显示剩余8条评论

65

设置扫描仪:

reader.useDelimiter("");
在执行该代码后,reader.next() 将返回一个单个字符的字符串。

reader.next()将返回一个单个字符的字符串。


19

没有API方法可以直接从Scanner中获取一个字符。你应该使用scanner.next()获取字符串,然后在返回的字符串上调用String.charAt(0)方法以获取第一个字符。

Scanner reader = new Scanner(System.in);
char c = reader.next().charAt(0);

为了确保字符串中不含有空格,您可以先调用trim()函数来移除所有的空格。

Scanner reader = new Scanner(System.in);
char c = reader.next().trim().charAt(0);

reader.next() 不是已经给你从第一个非空字符开始的字符串了吗? - norok2
但这会消耗整个字符串。 - VimNing

18

有三种方法来解决这个问题:

  • 在Scanner对象上调用next()方法,然后提取字符串的第一个字符(例如charAt(0))。如果你想读取该行其余的字符,请迭代字符串中剩下的字符。其他答案已经给出了这段代码。

  • 使用setDelimiter("")将分隔符设置为空字符串。这将导致next()将令牌化为恰好长度为1的字符串。因此,您可以重复地调用next().charAt(0)以迭代字符。接下来,您可以将分隔符设置回其原始值并正常恢复扫描!

  • 使用Reader API而不是Scanner API。 Reader.read()方法从输入流中读取单个字符。例如:

    Reader reader = new InputStreamReader(System.in);
    int ch = reader.read();
    if (ch != -1) {  // check for EOF
        // we have a character ...
    }
    

当你通过System.in从控制台读取输入时,通常情况下操作系统会对输入进行缓冲,并且只有在用户键入ENTER时才会“释放”给应用程序。因此,如果您希望您的应用程序响应于单个按键,这种方式是行不通的。您需要做一些针对操作系统级别下控制台关闭或解决行缓冲的特定于操作系统的本地代码工作。

参考:


这将导致next()将被分解为仅包含一个字符的字符串。因此,您可以重复调用__next().charAt(0)__来迭代字符。我认为您指的是next(),因为您已经使用了setDelimiter("")?但是对于您的第三点,我给予加1的赞赏。 - VimNing
不,我真的是指next().charAt(0)next调用返回一个String。所以如果你想要迭代char值,你需要调用charAt(0)来获取第一个字符。(这是Java,在这里一个字符和一个单字符字符串并不相同。)请注意,原贴明确说明了需要一个char - Stephen C

5
你可以很简单地解决这个“逐个字符获取键盘输入”的问题,而无需使用Scanner或清除输入缓冲区。只需使用以下方法即可。
char c = (char)System.in.read();

如果你只需要与C语言中的“getChar()”函数相同的功能,那么这个方法很好用。 "System.in.read()" 的一个巨大优势是缓冲区不会在获取每个字符后清除。所以如果你仍然需要用户输入的所有内容,你仍然可以从输入缓冲区获取其余部分。使用"char c = scanner.next().charAt(0);"的方式确实可以获取字符,但会清除缓冲区。
// Java program to read character without using Scanner
public class Main
{
    public static void main(String[] args)
    {
        try {
            String input = "";
            // Grab the First char, also wait for user input if the buffer is empty.
            // Think of it as working just like getChar() does in C.
            char c = (char)System.in.read();
            while(c != '\n') {
                //<do your magic you need to do with the char here>
                input += c; // <my simple magic>

                //then grab the next char
                c = (char)System.in.read();
            }
            //print back out all the users input
            System.out.println(input);
        } catch (Exception e){
            System.out.println(e);
        }
    }
}  

希望这篇文章能够帮到你,并祝你好运!附言:抱歉,我知道这是一篇较旧的帖子,但我希望我的答案能够带来新的见解,并可能帮助其他遇到相同问题的人。


4

实际上这并不起作用:

char c = reader.next().charAt(0);

这个问题中有一些好的解释和参考资料: 为什么Scanner类没有nextChar方法? “Scanner使用分隔符模式将其输入拆分为标记”,这是相当开放的。例如,当使用此时:
c = lineScanner.next().charAt(0);

针对这行输入:"(1 + 9) / (3 - 1) + 6 - 2",调用next函数返回"(1",变量c将被设置为'(',在下一次调用next()时会丢失数字'1'。

通常情况下,当你想获取一个字符时,你可能想忽略空格。以下方法适用于我:

c = lineScanner.findInLine("[^\\s]").charAt(0);

参考资料: 正则表达式匹配除空格外的单个字符


1
FYI "[^\\s]" === "\\S" - Bohemian

1

为了更快地获得结果,您应该使用自定义输入读取器,而不是从读取字符串中提取第一个字符。

自定义ScanReader和说明链接:https://gist.github.com/nik1010/5a90fa43399c539bb817069a14c3c5a8

扫描Char的代码:

BufferedInputStream br=new BufferedInputStream(System.in);
char a= (char)br.read();

你应该将代码片段中的代码添加到你的答案中,因为它可能随时无法访问。 - Markus
@Markus 添加了用于扫描字符的功能。 - NIKUNJ KHOKHAR

1
有两种方法,您可以 完全严格 取一个字符。 如果使用 "完全",无论您输入多少个字符,读者都只会取第一个字符。
例如:
import java.util.Scanner;  

public class ReaderExample {  

    public static void main(String[] args) {  

        try {  

        Scanner reader = new Scanner(System.in);

        char c = reader.findInLine(".").charAt(0);

            reader.close();  

            System.out.print(c);

        } catch (Exception ex) {  

            System.out.println(ex.getMessage());  

        }



    }  

}  

当您输入一组字符,比如“abcd”,阅读器只会考虑第一个字符,即字母'a'。
但是在使用strictly时,输入应该只有一个字符。如果输入的字符超过一个,则阅读器将不接受输入。
import java.util.Scanner;  

public class ReaderExample {  

    public static void main(String[] args) {  

        try {  

        Scanner reader = new Scanner(System.in);

        char c = reader.next(".").charAt(0);

            reader.close();  

            System.out.print(c);

        } catch (Exception ex) {  

            System.out.println(ex.getMessage());  

        }



    }  

}  

假设您输入了“abcd”,但没有接受输入,则变量c将具有空值。

1
在Scanner类中获取字符输入的最佳方法是:
Scanner sca=new Scanner(System.in);
System.out.println("enter a character");
char ch=sca.next().charAt(0);

1
import java.util.Scanner;

public class Test { 
    public static void main(String[] args) {
 
        Scanner reader = new Scanner(System.in);
        char c = reader.next(".").charAt(0);

    }
}

为了只获取一个字符,使用reader.next(".").charAt(0)

获取一个字符的方法:char c = reader.next(".").charAt(0); - Rakesh Kumar B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接