Цикл с условием продолжения, не читая в последнем объекте

Я пытаюсь читать во много строке строки, затем разделяет его, затем печатают его.. вот строка:

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;
} 
5
задан Earlz 14 April 2010 в 21:51
поделиться

9 ответов

Я уже написал ответ, это было решение. Но вы спрашиваете, что вы делаете не так.

  1. Вы используете Eclipse. Это неплохо, но если я попытаюсь сделать это в NetBeans, код будет работать немного иначе, потому что вы читаете и пишете в одном цикле . Итак, когда я копирую и вставляю ввод в eclipse, он работает так, как вы хотите. Но если я копирую и вставляю строку за строкой, это превращается в один большой беспорядок . Таким образом, вы должны разделить процесс чтения и записи.
  2. Что вы делаете неправильно, так это то, что вы сначала печатаете результат, а затем ( Почему? Я не знаю. Я думаю, вы тоже не знаете ... ) выполните print каждого символа в результате. В результате у вас есть только одна хорошая строка , а остальные начинаются с предыдущей строки.Итак:

      [строка 1]: foo 
     [строка 2]: foobar 
     [строка 3]: barbaz { {1}} [строка 4]: bazbam 
     

    Понимаете? Итак, начните с удаления вашего внутреннего цикла, который печатает каждый символ.
    Когда вы это сделали: ваш результат выглядит так:

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

    Итак, это причина, по которой вы подумали, что цикл foreach был проблемой. Если вы посмотрите на конец каждой выходной строки (ваш неправильный результат: опубликован в вопросе), вы увидите, что это было правильно.

  3. Затем вы хотите, чтобы на выходе была пустая строка, если она была на входе. Но, как я написал в своем другом ответе:

    Я ненавижу Сканер

    Сканер на самом деле читает не следующую строку, а следующее слово. Поэтому вам нужно изменить его на 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
ответ дан 18 December 2019 в 05:40
поделиться

Похоже, вы делаете больше работы, чем необходимо. Сканер может использовать настраиваемый разделитель; в вашем случае вы хотите, чтобы он разбивал ввод либо на новую строку, либо на удар, так что:

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)")

Без звездочки мы будем сопоставлять только одну вещь за раз: взрыв или новую строку (любого из трех найденных вариантов в разных операционных системах).

15
ответ дан 18 December 2019 в 05:40
поделиться

Может быть, потому что вы не нажали введите после последней строки ввода?

Обновление : протестировали здесь и подтвердили. Вам нужно нажать , ввести после последней строки ввода. Только так while (stdin.hasNext ()) вернет true и продолжит выполнение строки.

10
ответ дан 18 December 2019 в 05:40
поделиться

Я точно не знаю, что вы делаете. Вы читаете и печатаете в одно и то же время ... (Итак, я разделил ввод и вывод)

Лично я НЕНАВИЖУ класс 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)
0
ответ дан 18 December 2019 в 05:40
поделиться

Из документации Java SE 6 для java.util.Scanner.next () :

Находит и возвращает следующий полный токен от этого сканера. Перед полным токеном идет ввод , который соответствует шаблону разделителя . Этот метод может блокироваться, пока ожидает ввода для сканирования, даже если предыдущий вызов hasNext () вернул истину .

Я подозреваю, что в вашем коде Java произошло то, что приложение блокировало ожидание символа новой строки после последней строки.

2
ответ дан 18 December 2019 в 05:40
поделиться

У меня это работает, независимо от того, есть ли завершающий символ новой строки или нет. Конечно, определение «работает» неясно, за исключением того, что вы ожидали увидеть последнюю строку «4X1b1X», я полагаю. Я это видел.

C:\>java Main < test.txt
1T1b5T
1T1b5T1T2b1T1b2T
1T2b1T1b2T1T1b1T2b2T
1T1b1T2b2T1T3b1T1b1T
1T3b1T1b1T3T3b1T
3T3b1T1T3b1T1b1T
1T3b1T1b1T5T1*1T
5T1*1T11X21b1X
11X21b1X4X1b1X
4X1b1X
0
ответ дан 18 December 2019 в 05:40
поделиться
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


1
ответ дан 18 December 2019 в 05:40
поделиться

Проблема в сканере. Кажется, что все, что вам нужно, это читать строки. Для этого вам не нужен сканер (так как он не вернет последнюю часть, которая не разделена). Просто используйте 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);
            }
        }
    }

}
0
ответ дан 18 December 2019 в 05:40
поделиться

Сканер лучше по простоте. Это хуже с точки зрения детального контроля. Вам следует использовать какой-нибудь другой java.io.Reader, чтобы получить необходимый контроль.

Указание на , как перехватить пустой ввод с помощью класса сканера в java

0
ответ дан 18 December 2019 в 05:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: