2013-10-14 10 views
8

Uczę się Lua przez this site. Jestem na samym początku tutoriali i staram ten program (podaj numer, x, zwraca x!):Jak uzyskać lua do uruchamiania sekwencyjnego

-- defines a factorial function 
function fact (n) 
    if n == 0 then 
    return 1 
    else 
    return n * fact(n-1) 
    end 
end 

print("enter a number:") 
a = io.read("*number") -- read a number 
print(fact(a)) 

Jednak, gdy biegnę, tym io.read wydaje się pochodzić przed wierszu. Używam go w konsoli Notepad ++: tak:

"C:\Program Files\Lua\5.1\lua.exe" "Path\To\factorial.lua" 

Dane wyjściowe są (na pozór) puste, ale jeśli wprowadzę numer, funkcja zostanie uruchomiona.

5 
enter a number: 
120 

Chociaż nie jest wiele kwestii tutaj, mogę tylko wyobrazić sobie problemy, które pojawiają się od zmiennych przyzwyczaić przed stworzeniem. Jak mogę poprosić ten program, aby poprosił o podanie numeru przed odczytaniem danych wejściowych?

+0

Wypróbuj 'io.stdout: setvbuf "no" na początku twojego programu. –

+0

@EgorSkriptunoff Wydaje się działać poprawnie teraz. Możesz udzielić tej odpowiedzi. –

+3

Prosisz o zbyt wiele :-) –

Odpowiedz

13

To, co się dzieje, nie polega na tym, że kod kończy się niepowodzeniem, ale natychmiast nie jest wyświetlany monit do terminala.

Wewnętrznie wszystko, co wyprowadzasz, jest przechowywane w buforze we/wy przez system operacyjny. Okresowo bufor jest opróżniany, a jego zawartość jest wyświetlana na terminalu (jest to przepłukane). W większości systemów terminal jest domyślnie buforowany , co oznacza, że ​​za każdym razem, gdy piszesz znak końca wiersza - który jest automatycznie wykonywany przez print(), jest on przepłukiwany; w niektórych systemach domyślnie jest to w pełni buforowany, co oznacza, że ​​jest automatycznie opróżniany tylko wtedy, gdy się zapełnia.

Istnieją dwa sposoby rozwiązania tego problemu. Jeśli chcesz wyłączyć lub zmienić buforowanie dla operacji IOna pliku (i dla tych celów terminal liczy się jako plik), możesz użyć funkcji file:setvbuf(); w szczególności io.output():setvbuf("no") wyłącza buforowanie dla standardowego wyjścia, co oznacza, że ​​wszystko, co napiszesz, zostanie natychmiast wyświetlone. Można również użyć io.output():setvbuf("line"), aby włączyć buforowanie linii, w systemach, w których jest to obsługiwane, ale nie domyślne.

Drugie podejście polega na ręcznym przepłukaniu bufora, co jest przydatne, gdy chcesz od razu wyświetlić określone dane wyjściowe, ale nie chcesz, aby uniwersalne wyłączało buforowanie wyjściowe. Można to zrobić za pomocą funkcji file:flush(), który natychmiast opróżnia bufor, na przykład:

-- no newline, so even on line-buffered systems this may not 
-- display immediately 
io.write("Enter a number: ") 
-- so we force it to 
io.flush() 

Zauważ, że io.write() i io.flush() są tylko funkcje wygoda dla io.output():write() i io.output():flush(), to znaczy oni uzyskać aktualny plik wyjściowy, a następnie zadzwonić :write() lub :flush() na nich.

(Po co w ogóle buforować? Ponieważ jest szybszy - zapisywanie danych w terminalu lub pliku jest kosztowne, a pisanie jednej dużej rzeczy jest szybsze niż pisanie wielu małych rzeczy. W większości przypadków nie ma znaczenia jeśli rzeczy nie zostaną zapisane w chwili uruchomienia kodu, system operacyjny zapisuje dane, które mają być zapisane w buforze, a następnie wykonuje pojedyncze duże zapisy, gdy bufor się zapełni.)

+0

Bardzo pouczające. Świetna odpowiedź. –

Powiązane problemy