Reputation: 155
I have problems using get/1
or get0/1
. In both cases in SWI-Prolog a carriage return
is needed to finish the user input. Using it in a recursion this carriage return seems
to be "re-activated" in the next recursion loop. As result, no user input can be entered anymore. What's wrong?
My testcode:
test_userinput:-
repeat,
ask_user(Input),
write('You said: \n'),
write(Input),nl,
confirmation,
write('I understood.\n'),
define_end(Input).
end_of_use([x,'X','Q',q,a,'A',end,'END',e,'E']).
define_end(Input) :-
end_of_use(EndOfUse),
member(Input,EndOfUse).
ask_user(Input) :-
write('Pleaser enter a word or two:\n'),
read_line_to_codes(user_input,CodeInput),
atom_codes(Input,CodeInput).
confirmation :-
write('Right? [y/n]'),
get0(YN),
atom_codes(Input,[YN]),
member(Input,['y','Y']).
My output
8 ?- test_userinput.
Pleaser enter a word or two:
|: Hello World
You said:
Hello World
Right? [y/n] y
I understood.
Pleaser enter a word or two:
You said:
Right? [y/n] n
Pleaser enter a word or two:
You said:
Right? [y/n]
Action (h for help) ? abort
Using read_line_to_codes/2
instead of get0/1
it works:
read_line_to_codes(user_input,CodeInput),
atom_codes(Input,CodeInput),
The output
14 ?- test_userinput.
Pleaser enter a word or two:
| Hello World
You said:
Hello World
Right? [y/n] y
I understood.
Pleaser enter a word or two:
| ... and now without carriage return
You said:
... and now without carriage return
Right? [y/n] n
Pleaser enter a word or two:
| end
You said:
end
Right? [y/n] y
I understood.
true .
Would be a working solution, but I am looking for a method which does not need a carriage return entered by the user. Is there one in SWI Prolog?
Upvotes: 1
Views: 881
Reputation: 18663
When you only need to read a single character, you can use instead the get_single_char/1
built-in predicate. If you also want to echo the character the user entered, you can define a predicate such as:
read_single_char(Char) :-
get_single_char(Code), put_code(Code), nl, char_code(Char, Code).
See http://www.swi-prolog.org/pldoc/doc_for?object=get_single_char/1 for details. Note, however, that Carlos's solution is portable while the get_single_char/1
predicate is specific of SWI-Prolog.
Upvotes: 1
Reputation: 60024
I think you need to capture the enter character:
confirmation :-
write('Right? [y/n]'),
get_char(YN),
get_code(_),
member(YN,['y','Y']).
note: get/1 and get0/1 are deprecated
Upvotes: 0