我正在编写读取两个输入文件的代码,并检查第一个文件中的单词是否存在于第二个文件中。我想通过流程消息传递逐个检查列表中的元素。
这是我的代码:
[Day [dayNr=22, dayName=vendredi, sumOfHours=PT5M, hours=[Hour [hourNr=10, sumOfEntries=PT5M, entries=[TimeEntry [start=2016-01-22T10:00, duration=PT5M]]]]], Day [dayNr=23, dayName=samedi, sumOfHours=PT10M, hours=[Hour [hourNr=8, sumOfEntries=PT10M, entries=[TimeEntry [start=2016-01-23T08:00, duration=PT7M], TimeEntry [start=2016-01-23T08:43, duration=PT3M]]]]]]
问题在于,当我想发送列表的元素时,它只发送第一个元素。如何修改我的代码以发送所有字符串并检查它们?
答案 0 :(得分:1)
主要问题是您的check2/0
函数只接收一个元素然后退出。它需要循环以接收所有元素,并且还需要一些东西告诉它何时停止。让我们从start/0
开始逐个更改函数:
start()->
Pid2 = spawn(?MODULE,check2,[]),
check1(Pid2).
此处的更改是不需要生成check2/1
- 它可以直接由start/0
运行。
接下来,我们修改了check1/1
函数:
check1(Pid2) ->
{ok, Data} = file:read_file("input.txt"),
B = binary:split(Data, [<<" ">>,<<"\n">>], [global,trim_all]),
K = [binary_to_list(Item) || Item <- B],
[Pid2 ! Element || Element <- K++[stop]].
首先,我们为拆分模式添加了换行符,并且还添加了trim_all
选项以从拆分中删除空元素。我们还将原子stop
附加到我们发送给Pid2
的元素列表中。让我们看看修改后的check2/0
函数,看看原因:
check2() ->
{ok,IoDevice} = file:open("check.txt", [read]),
L = string:tokens(io:get_line(IoDevice,""), "! .\n"),
check2(L).
请注意,我们已将原始check2/0
拆分为两个功能:check2/0
和check2/1
。这是因为check2/1
函数必须是递归的,因此它可以接收发送给它的所有元素:
check2(L) ->
receive
stop ->
ok;
Element ->
case lists:member(Element,L)of
true ->
io:format("found: ~s\n", [Element]);
false ->
io:format("not found: ~s\n", [Element])
end,
check2(L)
end.
请注意,在receive
内我们首先检查我们是否已收到原子stop
,如果我们这样做,我们会退出该功能。否则,我们会收到并检查Element
,然后递归调用check2/1
,以便它可以接收下一个Element
或stop
原子。