0

我正在创建 swi-prolog 和 php 之间的接口。php 编写它希望 prolog 在文件上运行的命令,然后进行系统调用,以便 prolog 运行该文件。问题是当文件中有特殊字符(如á、í、ã、ê 等...)时,这些字符在 prolog 的输出中被 \uFFFD 替换,我知道此代码点用于未知/未识别codepoints,但我没有成功解决我在互联网上找到的问题。如果我自己从终端运行文件,它会显示正确的字符,就在 php 从 exec 或 shell_exec 运行时,它似乎失去了理由。

这是使用的代码,首先是php:

        $arquivo = fopen("/home/giz/prologDB/run.pl", w);
        $run = <<<EOT
    go :-   
        consult('/home/giz/prologDB/pessoasOps.pl'),
        addPessoa(0,'$name','$posicao','$resume','$unidade','$curso','$disciplina',$alunos,[]),
        halt.
EOT;

        echo $run;
        fwrite($arquivo, $run);

        $cmd = "prolog -f /home/giz/prologDB/run.pl -g go";     
        exec( $cmd, $output );
        echo "\n";      
        print_r( $output );   
        echo "\n"; 

序言代码:

addPessoa(LOCAL, NOME, POSICAO, RESUMO, UNIDADE, CURSO, DISCIPLINA, ALUNOS, REFERENCIA):-
    write( 'Prolog \nwas called \nfrom PHP \nsuccessfully.\n' ),    
    write('pessoa('),
    write(LOCAL),
    write(',\''),   
    write(NOME),
    write('\',\''),
    write(POSICAO),
    write('\',\''),
    write(RESUMO),
    write('\',\''),
    write(UNIDADE),
    write('\',\''),
    write(CURSO),
    write('\',\''),
    write(DISCIPLINA),
    write('\','),
    write(ALUNOS),
    write(','),
    write(REFERENCIA),
    write(').\n'),
    make.

有人知道如何让它正确解释字符串吗?

4

1 回答 1

0

Prolog 很可能需要 UTF-8 编码的字符,而您正在输入ISO-8859-n字符,其中 n 很可能是 1 或 15。在UTF-8中,当看到一个字节 >= 128 时,它要么是第一个多字节序列(如果 >= 192)或连续字节。如果多字节序列的第一个字节后面没有连续字节,或者如果序列以连续字节开头,则会得到无法识别的字节序列,在您的情况下为U+FFFD 代码点。在 ISO-8859-n 中,所有带变音符号的字符都在 128 以上。

还要查看swi-prolog 的有关 encoding 的手册页,尤其是以这两个句子开头的整个段落:

文件的默认编码来自 Prolog 标志 encoding,它是从环境初始化的。如果环境变量 LANG 以“UTF-8”结尾,则假定使用此编码。

当从 shell 或 PHP 中调用时 swi-prolog 的不同行为的一个很好的原因可能是LANG在这两种情况下环境变量的不同设置。但在同一段落中,手册提到了强制编码的方法。

在 shell 中,查看文件中包含的字节的最快方法是执行 an od -tx1z filename | less(在难以打印字符的情况下省略 z)。

于 2012-07-05T20:23:55.197 回答