我正在尝试读取多行字符串,然后将其拆分然后打印出来..这是字符串:
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;
}
答案 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)
我已经写了一个答案,这是一个解决方案。但你问的是你做错了什么。
你做错了是你首先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循环是问题的原因。如果你看一下每个输出行的结尾(错误的输出:在问题中发布),你可以看到,这是正确的。
如果输入中有一个空白行,那么您希望输出中有一个空行。但就像我在其他答案中写的那样:
我讨厌Scanner
扫描仪并没有真正读取下一行,而是下一行。所以你必须把它改成stdin.nextLine();
现在它可以了!
最后,这是您需要的代码:
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来获得您正在寻找的控件。
答案 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);
}
}
}
}