【问题标题】:Why doesn't the Scanner class have a nextChar method? [closed]为什么 Scanner 类没有 nextChar 方法? [关闭]
【发布时间】:2013-09-11 16:09:07
【问题描述】:

这真的是一个好奇心而不是一个问题......

为什么Scanner 类没有nextChar() 方法?当您考虑到它具有nextnextIntnextLine 等方法这一事实时,它似乎应该这样做。

我知道您可以简单地执行以下操作:

userChar = in.next().charAt(0);
System.out.println( userChar  );

但是为什么没有nextChar() 方法呢?

【问题讨论】:

  • 作为一种解决方法,您可以尝试next(".")
  • 查看源代码,next(".") 似乎会首先跳过分隔符(默认为空格)。也许这就是我们想要的。如果没有,您需要使用sc.delimiter() 保存当前分隔符模式,sc.useDelimiter(??) 将其设置为不匹配任何内容(可能是空模式,但我没有测试过); 那么 next(".");然后sc.useDelimiter 恢复之前的分隔符。

标签: java


【解决方案1】:

原因是 Scanner 类是为读取空格分隔的标记而设计的。它是一个包装底层输入流的便利类。在扫描仪之前,您所能做的就是读取单个字节,如果您想读取单词或行,那将是一个很大的痛苦。使用 Scanner,您传入 System.in,它会执行许多 read() 操作来为您标记输入。读取单个字符是更基本的操作。 Source

您可以使用(char) System.in.read();

【讨论】:

  • 是的,您可以使用它,但结果可能会相当混乱,因为 Scanner 会提前读取(和缓冲)字符……取决于前面的 Scanner API 调用。
【解决方案2】:

根据javadocScanner 似乎不适合读取单个字符。您将Scanner 附加到InputStream(或其他东西),它会为您解析输入。它还可以去除不需要的字符。因此,您可以轻松读取数字、线条等。当您只需要输入中的字符时,例如使用 InputStreamReader

【讨论】:

    【解决方案3】:

    要获得明确的原因,您需要询问该 API 的设计者。

    但一个可能的原因是(假设的)nextChar 的意图不太适合扫描模型。

    • 如果 nextChar()Reader 上的行为类似于 read() 并简单地从扫描仪返回下一个未使用的字符,那么它的行为与其他 next<Type> 方法不一致。它们在尝试解析值之前会跳过分隔符。

    • 如果nextChar() 表现得像(比如说)nextInt 那么:

      • 对于某些人来说,跳过分隔符是“意外的”,并且

      • 问题在于它是否应该接受单个“原始”字符,或者是char 的数字表示的数字序列,或者甚至可能支持转义或其他东西1.

    无论他们做出什么选择,有些人都不会高兴。我的猜测是设计师决定远离 tarpit。


    1 - 强烈支持原始字符方法......但关键是有需要分析的替代方案等。

    【讨论】:

      【解决方案4】:

      Scanner 类基于 String next(Pattern) 方法中实现的逻辑。额外的 API 方法,例如 nextDouble()nextFloat()。提供里面的图案。

      然后上课description says

      一个简单的文本扫描器,可以解析原始类型和字符串 使用正则表达式。

      扫描器使用分隔符模式将其输入分解为标记, 默认情况下匹配空格。然后生成的令牌可能是 使用各种 next 转换为不同类型的值 方法。

      从描述中可以遗憾的是,有人忘记了 char,因为它肯定是一种原始类型。

      但是类的概念是寻找模式,一个没有模式的字符就是下一个字符。恕我直言,这个逻辑导致 nextChar 没有实现。

      如果您需要逐个字符读取归档的字符,则可以使用更高效的类。

      【讨论】:

        【解决方案5】:

        我想这与编码有关。 char 是 16 个字节,某些编码将使用一个字节来表示一个字符,而另一种编码将使用两个甚至更多。最初设计 Java 时,他们假设任何 Unicode 字符都可以容纳 2 个字节,而现在一个 Unicode 字符最多需要 4 个字节(UTF-32)。 Scanner 无法在单个 char 中表示 UTF-32 代码点。

        您可以在构造实例时指定Scanner 的编码,如果未提供,它将使用平台字符集。但这仍然不能处理 3 或 4 字节 Unicode 字符的问题,因为它们不能表示为单个 char 原语(因为 char 只有 16 字节)。所以你最终会得到不一致的结果。

        【讨论】:

        • 我不明白。如果Scanner 因为无法识别编码而无法检索字符,它如何实现它的any 扫描方法?毕竟那些方法都要看字符,不是吗?
        • 您是指返回String 的方法吗?问题是,如果你有一个 4 字节的 unicode 字符,你将如何将其表示为 char?如果它是一个String,它可以在内部表示为一个char 数组,其中包含两个chars。但是,如果您正在处理 3 或 4 字节的 Unicode 字符,则无法从 nextChar 获得有意义的响应。
        • 据我所知,Reader 负责处理编码。看看docs.oracle.com/javase/1.5.0/docs/api/index.html?java/io/…
        • @VivinPaliath 如果您按照 Joachim 的建议使用 sc.next("."),如果有任何字符要返回,它将返回一个 1 字符的 String。如果Scanner因为编码问题不能返回一个字符,它也不能返回一个1字符的String。
        • @ajb 一个“字符”字符串在内部仍然由char[] 组成。如果您正在阅读 UTF-32 字符,nextChar 应该返回什么? String 可以算出,如果编码为UTF-32,则每个字符需要4个字节(因为您可以将编码指定为String)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-13
        • 1970-01-01
        • 2019-11-06
        相关资源
        最近更新 更多