Я пытаюсь читать во много строке строки, затем разделяет его, затем печатают его.. вот строка:
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;
}
Я уже написал ответ, это было решение. Но вы спрашиваете, что вы делаете не так.
Что вы делаете неправильно, так это то, что вы сначала печатаете
результат, а затем ( Почему? Я не знаю. Я думаю, вы тоже не знаете ... ) выполните print
каждого символа в результате. В результате у вас есть только одна хорошая строка , а остальные начинаются с предыдущей строки.Итак:
[строка 1]: foo
[строка 2]: foobar
[строка 3]: barbaz { {1}} [строка 4]: bazbam
Понимаете? Итак, начните с удаления вашего внутреннего цикла, который печатает каждый символ.
Когда вы это сделали: ваш результат выглядит так:
1T1b5T
1T2b1T1b2T
1T1b1T2b2T
1T3b1T1b1T
3T3b1T {{1 }} 1T3b1T1b1T
5T1 * 1T
11X21b1X
4X1b1X
Итак, это причина, по которой вы подумали, что цикл foreach был проблемой. Если вы посмотрите на конец каждой выходной строки (ваш неправильный результат: опубликован в вопросе), вы увидите, что это было правильно.
Затем вы хотите, чтобы на выходе была пустая строка, если она была на входе. Но, как я написал в своем другом ответе:
Я ненавижу Сканер
Сканер на самом деле читает не следующую строку, а следующее слово. Поэтому вам нужно изменить его на 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);
}
}
Похоже, вы делаете больше работы, чем необходимо. Сканер
может использовать настраиваемый разделитель; в вашем случае вы хотите, чтобы он разбивал ввод либо на новую строку, либо на удар, так что:
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)")
Без звездочки мы будем сопоставлять только одну вещь за раз: взрыв или новую строку (любого из трех найденных вариантов в разных операционных системах).
Может быть, потому что вы не нажали введите после последней строки ввода?
Обновление : протестировали здесь и подтвердили. Вам нужно нажать , ввести после последней строки ввода. Только так while (stdin.hasNext ())
вернет true
и продолжит выполнение строки.
Я точно не знаю, что вы делаете. Вы читаете и печатаете в одно и то же время ... (Итак, я разделил ввод и вывод)
Лично я НЕНАВИЖУ класс 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)
Из документации Java SE 6 для java.util.Scanner.next ()
:
Находит и возвращает следующий полный токен от этого сканера. Перед полным токеном идет ввод , который соответствует шаблону разделителя . Этот метод может блокироваться, пока ожидает ввода для сканирования, даже если предыдущий вызов
hasNext ()
вернулистину
.
Я подозреваю, что в вашем коде Java произошло то, что приложение блокировало ожидание символа новой строки после последней строки.
У меня это работает, независимо от того, есть ли завершающий символ новой строки или нет. Конечно, определение «работает» неясно, за исключением того, что вы ожидали увидеть последнюю строку «4X1b1X», я полагаю. Я это видел.
C:\>java Main < test.txt
1T1b5T
1T1b5T1T2b1T1b2T
1T2b1T1b2T1T1b1T2b2T
1T1b1T2b2T1T3b1T1b1T
1T3b1T1b1T3T3b1T
3T3b1T1T3b1T1b1T
1T3b1T1b1T5T1*1T
5T1*1T11X21b1X
11X21b1X4X1b1X
4X1b1X
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 возвращает массив с элементами, разделенными знаком "!". { {1}} Метод printout просто выводит элементы массива в стандартный вывод в виде отдельных строк.
Весь 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
Проблема в сканере. Кажется, что все, что вам нужно, это читать строки. Для этого вам не нужен сканер (так как он не вернет последнюю часть, которая не разделена). Просто используйте 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);
}
}
}
}
Сканер лучше по простоте. Это хуже с точки зрения детального контроля. Вам следует использовать какой-нибудь другой java.io.Reader, чтобы получить необходимый контроль.
Указание на , как перехватить пустой ввод с помощью класса сканера в java