I am writing code that reads two input files and checks if the words in the first file are present in the second file. I want to check elements of the list one by one via process message passing.
Here is my code:
start()->
Pid2 = spawn(?MODULE,check2,[]),
spawn(?MODULE,check1,[Pid2]).
check1(Pid2) ->
{ok, Data} = file:read_file("input.txt"),
B = binary:split(Data, [<<" ">>], [global]),
K = [binary_to_list(Item) || Item <- B],
[Pid2 ! Element || Element <- K].
check2() ->
{ok,IoDevice} = file:open("check.txt", [read]),
L = string:tokens(io:get_line(IoDevice,""), "! ."),
receive
Element ->
case lists:member(Element,L)of
true ->
io:format(Element);
false ->
io:format("not_ok")
end
end.
The problem is that when I want to send an element of the list, it sends just the first element. How can I modify my code to send all strings and check them?
The primary issue is that your
check2/0
function only receives a single element and then exits. It needs to loop to receive all elements, and it also needs something to tell it when to stop. Let's change the functions one by one below, starting withstart/0
:The change here is that there's no need to spawn
check2/1
— it can just be run directly bystart/0
.Next, here's our revised
check1/1
function:First, we added newline to the split pattern, and also the
trim_all
option to get rid of empty elements from the split. We also appended the atomstop
to the list of elements we send toPid2
. Let's look at our revisedcheck2/0
function to see why:Note that we've split the original
check2/0
into two functions:check2/0
andcheck2/1
. This is because thecheck2/1
function has to be recursive so it can receive all the elements sent to it:Notice that inside the
receive
we first check to see if we've received the atomstop
, and if we do, we exit the function. Otherwise, we receive and check anElement
, and after that callcheck2/1
recursively so it can receive either the nextElement
or thestop
atom.