2

すべてのサブディレクトリのリストをファイルに書き込もうとしていますが、サブディレクトリ名の Unicode 記号が疑問符に置き換えられます。Windows XP で CLISP 2.49 を使用しています。

コードの短いバージョンは次のとおりです。

(let ((*pathname-encoding* (ext:make-encoding :charset 'charset:utf-8
                                              :line-terminator :dos)))
    (with-open-file (stream "folders.txt"
                     :direction :output
                     :if-exists :overwrite
                     :if-does-not-exist :create
                     :external-format (ext:make-encoding :charset 'charset:utf-8
                                                         :line-terminator :dos))
       (format stream "~A~&" (directory ".\\*\\"))))
4

1 に答える 1

2

あなたが間違っていること

は変数ではなくSYMBOL-MACRO*pathname-encoding*であることに注意してください。CLISPマニュアルの注記にあるように、

注意: SYMBOL-MACROにはEXT:LETF/EXT:LEETF*を使用する必要があります。 LET/LET*は機能しません!

だから、あなたがする必要があるのは

(ext:letf ((*pathname-encoding* charset:utf-8)) ...)

(とにかくのline-terminatorモード*pathname-encoding*は無視されます)。

$ touch 'идиотский файл'
$ ls
идиотский файл
$ LANG=C ls
?????????????????? ????????
$ LANG=C clisp -q -norc 
> *pathname-encoding* 
#<ENCODING CHARSET:ASCII :UNIX>
> *default-file-encoding* 
#<ENCODING CHARSET:ASCII :UNIX>
> *terminal-encoding* 
#<ENCODING CHARSET:ASCII :UNIX>
> (letf ((*pathname-encoding* charset:utf-8))
    (with-open-file (o "foo" :direction :output :external-format charset:utf-8) 
      (format o "~A~%" (directory "*"))))
NIL
> (quit)
$ cat foo
(/home/sds/tmp/z/идиотский файл /home/sds/tmp/z/foo)

特定の問題のデバッグ

CLISP は、処理できない文字の代わりに出力したり返したり?することはありません - エラーを通知します (エンコーディング仕様の 1 つを省略しようとすると、Invalid byte #xD0 in CHARSET:ASCII conversionfromwriteまたは fromのいずれかでエラーが発生しますdirectory)。

したがって、問題は境界にあります。

  • OS が Unicode の代わりに CLISP にクエスチョン マークを付けるか (CLISP は i18n を処理できないと考えているため)
  • または、CLISP によって生成されたファイルが、低レベルの OS レイヤーによって誤って保存されます。
  • または、ファイルを表示するために使用しているツールが Unicode 文字を表示できない

(最後のオプションだけがもっともらしく見えます)。

あなたができることは次のとおりです。

  1. エンコーディング仕様の削除から始めます - 変換エラーが発生しますか? デフォルトのエンコーディングの場所*pathname-encoding*を調べます (これは&cのようなシンボル マクロを表す Lisp の凝った言葉です)
  2. *pathname-encoding*であることを確認してutf-8、次のようなことを試してください(coerce (pathname-name (car (directory "*"))) 'list)-上記の私の例では(#\CYRILLIC_SMALL_LETTER_I ...)、私のようにユニコード文字が見えますか、それとも見え#\?ますか?
  3. cygwin( lsls | od、 ) を試して、 ls > foo; cat foo | odASCII 以外の文字をキャプチャできるかどうかを確認してください。
于 2013-04-24T13:22:19.673 に答える