2012-02-02 24 views
2

テキストファイルからLispのデータ(実際には配列)を読み込もうとしています。 with-open-fileread-lineのものを使用しようとしましたが、目標を達成できませんでした。私が探しているのは、MATLABでdata=load('filename.txt')を実行するのと同じです。という配列を取得し、filename.txtにすべての情報をロードしました。Common Lispのテキストファイルから配列を読み取る

テキストファイルは

1.0 2.0 3.0 ... 
1.5 2.5 3.5 ... 
2.0 3.0 4.0 ... 
..... 

も変えることができる大きさのような形式になります。ありがとうございます。

+3

何を試しましたか? –

答えて

3

split-sequence(のライブラリーから同じ名前)をフィールドに分割し、parse-number(同じ名前)を使用して文字列を数値に変換します。上記のライブラリはすべてQuicklispから入手できます。

EDIT:

(defun load-array-from-file (filename) 
    (with-open-file (in filename 
         :direction :input) 
    (let* ((data-lol (loop :for line := (read-line in nil) 
          :while line 
          :collect (mapcar #'parse-number:parse-number 
              (cl-ppcre:split "\\s+" line)))) 
      (rows (length data-lol)) 
      (columns (length (first data-lol)))) 
     (make-array (list rows columns) 
        :initial-contents data-lol)))) 

あなたはいくつかのチェックを追加し、それらが満たされない場合には取得したいのかを考える必要があります:

ちょうどあなたが始めるために、これは検証せずに簡易版です
  • 行はすべて同じ長さですか?
  • すべてのフィールドは有効な数字ですか?
3

あなたの質問に書かれている書式設定パターンに従っていると仮定します。空白で区切られた一連の数字です。これは簡単なスニペットです。

(defun read-array (filename) 
    (with-open-file (in filename) 
    (loop for num = (read in nil) 
      until (null num) 
      collect num))) 
+1

ユーザーの入力を解析するためにリーダーを使用することは、通常はお勧めできません。 – Svante

+0

@Svante:プログラムを実行している同じユーザーがデータを提供している場合、どこに問題がありますか? –

+0

@Rörd:プログラム/システムは、外部のものと内部のものを安全に区別することができます。それは外部で起こっていることを推測すべきではありません。 – Svante

1

もう1つの方法は、テキストファイル内のデータを解析するためにlispリーダーを活用することです。これを行うには、私はおそらく最初の文字列にファイル全体を変換して、例えば

(eval (read-from-string (format nil "~a~a~a" "(initial wrapper code " str ")"))) 

呼びたい、あなたは空白/改行で区切られたすべての数字であるデータファイルに読みたい場合、リストに、前のコマンドが次のようになります。それを行うための基本的な方法は、行を取得するには、入力ストリームを取得するためloopread-linewith-open-fileを使用することです

(eval (read-from-string (format nil "~a~a~a" "(list " str ")"))) 
1

私はSvanteの助言に従った。私はちょうどテキストファイル内に単一の列が必要でしたが、これは私がこの目的のために使用しているものです。

(defun load_data (arr column filename) 
(setf lnt (first (array-dimensions arr))) 
(with-open-file (str (format nil "~A.txt" filename) :direction :input) 
    (loop :for i :from 0 :to (1- lnt) :do 
     (setf (aref arr i 0) (read-from-string (nth (1- column) (split-sequence:SPLIT-SEQUENCE #\Space (read-line str)))))))) 

ありがとうございました。

関連する問題