虽然循环没有在最后一项中读取

时间:2010-04-06 12:19:48

标签: java c

我正在尝试读取多行字符串,然后将其拆分然后打印出来..这是字符串:

1T1b5T!1T2b1T1b2T!1T1b1T2b2T!1T3b1T1b1T!3T3b1T!1T3b1T1b1T!5T1*1T

11X21b1X
4X1b1X

当我用!分割字符串时,我得到的是没有最后一行字符串:

1T1b5T
1T1b5T1T2b1T1b2T
1T2b1T1b2T1T1b1T2b2T
1T1b1T2b2T1T3b1T1b1T
1T3b1T1b1T3T3b1T
3T3b1T1T3b1T1b1T
1T3b1T1b1T5T1*1T
5T1*1T11X21b1X
11X21b1X

这是我的代码:

import java.io.BufferedInputStream;
import java.util.Scanner;

public class Main {

    public static void main(String args[]) {
        Scanner stdin = new Scanner(new BufferedInputStream(System.in));
        while (stdin.hasNext()) {
            for (String line : stdin.next().split("!")) {
                System.out.println(line);

                for (int i = 0; i < line.length(); i++) {
                    System.out.print(line.charAt(i));
                }
            }
        }
    }

}

我在哪里弄错了,为什么不在最后一行阅读?在我正确阅读所有行之后,如果我遇到数字,我应该通过每一行我应该打印下一个字符,这是我刚读过的数字的n倍,但这还有很长的路要走,首先我需要帮助。谢谢

更新:

以下是输出的外观:

1T1b5T
1T2b1T1b2T
1T1b1T2b2T
1T3b1T1b1T
3T3b1T
1T3b1T1b1T
5T1*1T

11X21b1X
4X1b1X

这是C中的一个解决方案(我的朋友解决了它而不是我),但我很想在JAVA中做到这一点:

#include <stdio.h>

int main (void)
{
    char row[134];
    for (;fgets (row,134,stdin)!=NULL;)
    {
        int i,j=0;
        for (i=0;row[i]!='\0';i++)
        {
            if (row[i]<='9'&&row[i]>='1')
                j+=(row[i]-'0');
            else if ((row[i]<='Z'&&row[i]>='A')||row[i]=='*')
                for (;j;j--)
                    printf ("%c",row[i]);
            else if (row[i]=='b')
                for (;j;j--)
                    printf (" ");
            else if (row[i]=='!'||row[i]=='\n')
                printf ("\n");
        }
    }
    return 0;
} 

9 个答案:

答案 0 :(得分:15)

你似乎做了比必要更多的工作。 Scanner可以使用自定义分隔符;在你的情况下,你希望它打破换行或爆炸的输入,所以:

Scanner stdin = new Scanner(System.in);
stdin.useDelimiter("[!\\s]*"); // Break on any combination of whitespace characters and !s

while (stdin.hasNext()) {        // While there's a next token,
    String line = stdin.next();  // read it in
    System.out.println(line);    // and print it out.
}

你正在用你的打印声明做一些不可思议的事情 - 上面的代码假定你想要做的就是打印出每一行。您似乎试图在代码中执行两次,因此如果我误解了您的意图,请进行适当修改。

根据您的更新进行修改:好的,您希望允许空令牌并将其传递完毕。这很简单:只需修改分隔符,使其只匹配一个字符,如下所示:

stdin.useDelimiter("(!|\\r?\\n|\\r)")

没有星号,我们一次只能匹配一件事:爆炸或换行(在不同操作系统上找到的三种口味中的任何一种)。

答案 1 :(得分:10)

也许是因为你没有在最后一个输入行后点击输入

更新:在此测试并确认。你需要在最后一个输入行后点击输入。只有这样,while (stdin.hasNext())才会返回true并继续行。

答案 2 :(得分:3)

我已经写了一个答案,这是一个解决方案。但你问的是你做错了什么。

  1. 您正在使用Eclipse。这还不错,但是如果我尝试在NetBeans中执行此操作,则代码会起作用,因为您 在同一循环中读取和写入 。所以当我在eclipse中复制粘贴输入时,它可以按你的需要工作。但是,如果我逐行复制粘贴,它会变成一大块混乱。所以你必须拆分读取和写入过程。
  2. 你做错了是你首先println结果然后(为什么?我不知道。我认为你也不知道...... )在结果中执行每个char的print。因此,结果是您只有一条好行,而其他行则由前一行启动。所以:

    [line 1]: foo
    [line 2]: foobar
    [line 3]: barbaz
    [line 4]: bazbam
    
    你知道吗?因此,首先要删除打印每个字符的内部循环 当你这样做时:你的输出如下:

    1T1b5T
    1T2b1T1b2T
    1T1b1T2b2T
    1T3b1T1b1T
    3T3b1T
    1T3b1T1b1T
    5T1*1T
    11X21b1X
    4X1b1X
    

    所以这就是为什么你认为foreach循环是问题的原因。如果你看一下每个输出行的结尾(错误的输出:在问题中发布),你可以看到,这是正确的。

  3. 如果输入中有一个空白行,那么您希望输出中有一个空行。但就像我在其他答案中写的那样:

      

    我讨厌Scanner

    扫描仪并没有真正读取下一行,而是下一行。所以你必须把它改成stdin.nextLine();现在它可以了!


  4. 最后,这是您需要的代码:

    Scanner stdin = new Scanner(new BufferedInputStream(System.in));
    while (stdin.hasNext()) {
        String line = stdin.nextLine();
        for (String part : line.split("!")) {
            System.out.println(part);
        }
    }
    

答案 3 :(得分:2)

来自java.util.Scanner.next()的Java SE 6文档:

  

查找并返回下一个完整的内容   来自此扫描仪的令牌。一套完整的   令牌前面和后面跟着   与分隔符匹配的输入   图案。这种方法可能会阻止   等待输入扫描,即使是   以前调用hasNext()   已退回true

我怀疑你的Java代码中发生的事情是应用程序在最后一行之后阻止等待换行符。

答案 4 :(得分:1)

public static List<String> ppp(final String source) {
    final ArrayList<String> result = new ArrayList<String>();
    final Scanner scan = new Scanner(source);
    scan.useDelimiter("!");
    while (scan.hasNext()) {
    result.add(scan.next());
    }
    return result;
}

private static void printout(final List<String> someArgs) {
    final Iterator<String> i = someArgs.iterator();
    while (i.hasNext()) {
    System.out.println(i.next());
    }
} 
public static void main(final String[] args) throws IOException {
    final String lineSeparator = System.getProperty("line.separator");
    final String test = "1T1b5T!1T2b1T1b2T!1T1b1T2b2T!1T3b1T1b1T!3T3b1T!1T3b1T1b1T!5T1*1T"
            + lineSeparator + lineSeparator + "11X21b1X" + lineSeparator + "4X1b1X" + lineSeparator;
    System.out.println("Source: ");
    System.out.println(test);
    System.out.println("Result as List: ");
    System.out.println(ppp(test));
    System.out.println("Result in lines:");
    printout(ppp(test));}

String测试是一个多行字符串,其中包含LineSeparators。 方法ppp返回一个数组,其元素用“!”分隔。 方法printout只是将数组的元素打印到分隔行中的stdout。

整个main()生成以下输出:

Source: 
1T1b5T!1T2b1T1b2T!1T1b1T2b2T!1T3b1T1b1T!3T3b1T!1T3b1T1b1T!5T1*1T

11X21b1X
4X1b1X

Result as List: 
[1T1b5T, 1T2b1T1b2T, 1T1b1T2b2T, 1T3b1T1b1T, 3T3b1T, 1T3b1T1b1T, 5T1*1T

11X21b1X
4X1b1X
]
Result in lines:
1T1b5T
1T2b1T1b2T
1T1b1T2b2T
1T3b1T1b1T
3T3b1T
1T3b1T1b1T
5T1*1T

11X21b1X
4X1b1X


答案 5 :(得分:0)

无论是否有尾随换行符,它都适用于我。当然,“作品”的定义还不清楚,除非您预计会看到最后一行“4X1b1X”。我确实看到了。

C:\>java Main < test.txt
1T1b5T
1T1b5T1T2b1T1b2T
1T2b1T1b2T1T1b1T2b2T
1T1b1T2b2T1T3b1T1b1T
1T3b1T1b1T3T3b1T
3T3b1T1T3b1T1b1T
1T3b1T1b1T5T1*1T
5T1*1T11X21b1X
11X21b1X4X1b1X
4X1b1X

答案 6 :(得分:0)

我不知道你在做什么。您正在同时阅读和打印...(所以我分割了输入和输出)

Personnaly,我 HATE Scanner类。我总是使用BufferedReader。

因此,我首先将输入存储在列表中。因此用户可以在没有agressif输出的情况下输入。输入后,您可以简单地打印它。

我按照以下方式做了,它的工作正确:

public static void main(String[] args) throws IOException {
    List<String> lines = new ArrayList<String>();
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    System.out.print("How many lines count the input? ");
    int count = Integer.parseInt(reader.readLine());
    for (int i = 0; i < count; i++)
    {
        lines.add(reader.readLine());
    }
    System.out.println("\nNow comes the output:");
    for (int i = 0; i < count; i++)
    {
        String line = lines.get(i);
        String[] splitted = line.split("!");
        for (String string : splitted) {
            System.out.println(string);
        }
    }
}

这是我运行的方式:

How many lines count the input? 4
1T1b5T!1T2b1T1b2T!1T1b1T2b2T!1T3b1T1b1T!3T3b1T!1T3b1T1b1T!5T1*1T

11X21b1X
4X1b1X


Now comes the output:
1T1b5T
1T2b1T1b2T
1T1b1T2b2T
1T3b1T1b1T
3T3b1T
1T3b1T1b1T
5T1*1T

11X21b1X
4X1b1X
BUILD SUCCESSFUL (total time: 10 seconds)

答案 7 :(得分:0)

扫描仪在简单性方面更胜一筹。在细粒度控制方面更糟糕。 您应该使用其他一些java.io.Reader来获得您正在寻找的控件。

指向how to catch blank input with scanner class in java

答案 8 :(得分:0)

问题是扫描仪。似乎所有你想做的就是读取行。为此,您不需要扫描仪(因为它不会返回未分隔的最后一个部分)。只需使用缓冲读卡器的readLine:

import java.io.BufferedInputStream;
import java.util.Scanner;

public class Main {

    public static void main(String args[]) {
        BufferedInputStream stdin = new Scanner(new BufferedInputStream(System.in));
        String line;
        while ((line=stdin.nextLine)!=null) {
            for (String token : line.split("!")) {
                System.out.println(token);
            }
        }
    }

}