Smalltalk stdin nextLine для фиксированного количества строк ввода

В настоящее время я пытаюсь получить 3 конкретные строки ввода формы:

XX.XX (с плавающей точкой) XX (1-3-значное целое число) XX (1-3-значное целое число)

Ниже приведен текущий код, который у меня есть:

inputStringOne := stdin nextLine.
mealCost := inputStringOne.

Transcript show: inputStringOne; cr .

inputStringTwo := stdin nextLine.
tipPercent := inputStringTwo.

Transcript show: inputStringTwo; cr .

inputString := stdin nextLine.
taxPercent := inputString .

mealCost inspect .
tipPercent inspect .
taxPercent inspect .

Я занимался этим 3-4 часа, программируя, изучая Интернет и т. Д. Я начинающий учить себя Smalltalk, поэтому я пытаюсь понять, почему nextLine не правильно читает входные данные. Ниже приведены примеры входных данных, помещенных в stdin, и результаты стенограммы показывают и проверяют:

Пример ввода на стандартном вводе:

10.25
17
5

Вывод на стандартный вывод:

10.25
.25
An instance of String
  contents: [
    [1]: $1
    [2]: $0
    [3]: $.
    [4]: $2
    [5]: $5
  ]
An instance of String
  contents: [
    [1]: $.
    [2]: $2
    [3]: $5
  ]
An instance of String
  contents: [
    [1]: $.
    [2]: $2
    [3]: $5
  ]
10.25

Когда я просто делаю следующий код, я вижу все 3 входа, разделенных <10>, которые я предполагаю, что это возврат каретки или перевод строки.

"just print all contents in stdin"
inputS := stdin contents.
inputS inspect .

Пример ввода (стандартный):

10.25
17
5

Выход (стандартный вывод):

An instance of String
  contents: [
    [1]: $1
    [2]: $0
    [3]: $.
    [4]: $2
    [5]: $5
    [6]: $<10>
    [7]: $1
    [8]: $7
    [9]: $<10>
    [10]: $5
  ]

Так что кажется, что по какой-то причине первая строка кода была получена stdin nextLine ., но остальные получают только последние 3 символа (десятичную точку и 2 цифры после десятичной точки). Я не уверен, почему это так.

я пытался nextAvailable, flush, commit, stdin closeи несколько других методов, но все безрезультатно. У меня есть одна идея, чтобы обойти эту проблему, просто получить всю stdin contents, разделить на <10>, затем сохранить каждую "деталь" в 3 разных переменных, но я хочу узнать больше о том, как stdin nextLine работает и иметь лучшее понимание того, как это относится к stdin contents также. Нет ли хорошего способа просто сделать stdin nextLine 3 раза, учитывая, что мы знаем, что есть только 3 входа?

3 ответа

Это похоже на ошибку в GNU smalltalk. Если вы введете ввод непосредственно с клавиатуры, то stdin nextLine работает просто отлично. Однако если вы перенаправите ввод из файла, то stdin nextLine портит это.

Примечательно, что я не могу найти ни одного ответа в HackerRank, который написан на smalltalk, так что это должно быть старой проблемой.

используя очень глючную версию smalltalk на другом сайте. Лучший подход, который я смог найти, основывается на содержимом. Примечание: массив в smalltalk начинается с 1, а не с 0.

      ins := stdin contents substrings '\n'.

loopMax := 3.
ix := 1.
[   line := ins at: ix.
    Transcript show: 'ins at ', ix printString;
        show: ' =', line; cr.
                
    ix := ix + 1.
    b := ix asNumber > loopMax.
] whileFalse: [ b ].

Я не могу воспроизвести это на macOS с GNU Smalltalk 3.2.5:

→ gst -f foo.st
12.23
12.23
12
12
7
An instance of String
  contents: [
    [1]: $1
    [2]: $2
    [3]: $.
    [4]: $2
    [5]: $3
  ]
An instance of String
  contents: [
    [1]: $1
    [2]: $2
  ]
An instance of String
  contents: [
    [1]: $7
  ]

Как вы можете видеть, каждый вход отражается от вашего Transcript show: сообщения и вывод inspect тоже выглядит правильно. Какую ОС и версию GNU Smalltalk вы используете?

Другие вопросы по тегам