2011-11-27 43 views
6

Bir listeye girmeye ve bir dosyaya yazmaya çalışıyorum, neden aşağıdaki çalışmıyor? İlkDosyaya yazılıyor (Prolog)

loop_through_list(List) :- 
    member(Element, List), 
    write(Element), 
    write(' '), 
    fail. 

write_list_to_file(Filename,List) :- 
    tell(Filename),  % open file to be written 
    loop_through_list(List), 
    told.    % flush buffer 
+1

'Write_list_to_file/2' çalıştırırken oluşturduğunuz dosyaya bakın! Muhtemelen, yalnızca listenin içindeki öğeleri değil, aynı zamanda dosyanın sonundaki diğer istenmeyen verileri de içerir. Diğerleri zaten belirttiği gibi, 'open/3' ve' close/1' kullanmak daha güvenlidir. – false

+0

Güvenilmezlik hakkındaki bilgilerin nerede bulunduğunu merak ettim, beni kaynağa yönlendirebilir misiniz? – chutsu

+1

Burada bir açıklama bulabilirsiniz (burada) (http://stackoverflow.com/questions/8269971/prolog-how-to-save-file-in-an-existing-file/8270091#8270091) – false

cevap

7

, başarısız neden:
Sen ancak orada iyi bir teknik olabilir backtracking, kışkırtmak için başarısız kullanın. Çünkü üye, çözümlerin tükendiği zaman, yükleminizi yanlış yapacaktır. Daha sonra, loop_through_list öğesi false olduğunda, ulaşılmadığı ve yazının düzgün yapılmadığı (bunu test ettiğimde, dosya oluşturulur, ancak hiçbir şey yazılmaz).
Eğer kullanıyorsanız:

loop_through_list([]). 
loop_through_list([Head|Tail]) :- 
    write(Head), 
    write(' '), 
    loop_through_list(Tail). 

yerine, işe yarıyor.

Ancak, bu kod çalışırken bile, open (Filename, write, Stream), write (Stream, Element) ve close (Stream) kullanmak yerine bağlantıda açıklanan nedenleri anlatmak isteyebilirsiniz. bu cevabın alt kısmında. Örneğin
:

loop_through_list(_File, []) :- !. 
loop_through_list(File, [Head|Tail]) :- 
    write(File, Head), 
    write(File, ' '), 
    loop_through_list(File, Tail). 

write_list_to_file(Filename,List) :- 
    open(Filename, write, File), 
    loop_through_list(File, List), 
    close(File). 

veya

loop_through_list(File, List) :- 
    member(Element, List), 
    write(File, Element), 
    write(File, ' '), 
    fail. 

write_list_to_file(Filename,List) :- 
    open(Filename, write, File), 
    \+ loop_through_list(File, List), 
    close(File). 

kodunuzu ve joel76 hile kullanarak

.

Bkz. Prolog how to save file in an existing file
Aynı konuyu kapsar.

+0

Bu arada '\ +'? Bu, (örneğin, C'deki '!') anlamına gelmez. – chutsu

+1

@chutsu: evet, öyle. En azından SWI-pl'de (ve diğerleri size diğer uygulamalar hakkında bilgi verebilir), ** değil/1 ** kullanımdan kaldırılmıştır ve bu [manuel sayfa] 'da belirtildiği gibi ** \ +/1 ** kullanılması önerilmektedir (http : //www.swi-prolog.org/pldoc/doc_for nesne = değildir/1) – m09

2

yüklem loop_through_list (Liste), daima

3

Ben yazmak için kullanacağım bu yöntemi yapmak için bir neden göremiyorum, bu yüzden sadece \ + loop_through_list (Liste) yazmak zorunda succed, başarısız bir dosyaya listeleyin.
Prologda programlama genellikle döngü içermemelidir;
Ayrıca, bu bir döngü yapısı değil, daha çok bir kesmek (hatta kötüye kullanım).
(ve vaka beklenmedik hatalar ve sorunlara yol açar gibi)

Sadece özyinelemeye kullanmak ve listenin elemanlarını yazdırmak:

write_list([]). 
write_list([H|T]):- 
    write(H), 
    write(' '), 
    write_list(T). 

daha şık ve çok daha verimli olabilir. Bunun dışında, tell/1 etc yerine (Edinburgh IO) açık/4 vb (ISO IO) kullanılması genelde daha iyidir; false's post