kiw
kiw

Reputation: 155

User input in SWI Prolog, problems with carriage return

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

Answers (2)

Paulo Moura
Paulo Moura

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

CapelliC
CapelliC

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

Related Questions