如何使用格式化打印在Haskell中为CGI显示UTF-8?

Cha*_*lie 2 printf haskell cgi utf-8

我有一个代码

module Main where

import Text.Printf

main = printf "%s%s" ("Content-type: text/html; charset=utf-8\n\n" :: String ) ("And ??????? ????????" :: String)
Run Code Online (Sandbox Code Playgroud)

如果我在终端执行它,我有我想要的:

Content-type: text/html; charset=utf-8

And ??????? ????????
Run Code Online (Sandbox Code Playgroud)

但是当我尝试将其作为cgi-program执行时,我只是And(因为在这个词之后我有西里尔字符并且他们不想显示).

有没有问题,当我使用putStr $ fromStringData.ByteString.Char8Data.ByteString.UTF8,所以我不认为有一个与我LAMPP服务器有问题.我也包含AddDefaultCharset utf-8在httpd.conf中.

而我想要做的就是读取带有特殊符号的模板文件%s,%d等等,然后在帮助下printf,根据查询字符串和显示,将它们(符号)替换为我需要的符号.

我这样做只是为了好玩,我希望这个问题只用纯Haskell解决.

Joa*_*ner 7

使CGI程序依赖于语言环境可能适合也可能不适合; 例如,如果您生成的HTML有一个编码标题,说它是UTF-8,那么您应该独立于系统区域设置生成UTF-8.

与语言环境无关的方法是在打印任何内容之前设置stdout的编码:

import System.IO

main = do
    hSetEncoding stdout utf8
    printf "%s%s" ("Content-type: text/html; charset=utf-8\n\n" :: String ) ("And ??????? ????????" :: String)
Run Code Online (Sandbox Code Playgroud)

你的代码:

/tmp $ echo $LANG
de_DE.utf8
/tmp $ ./Test2
Content-type: text/html; charset=utf-8

And ??????? ????????
/tmp $ LANG=C ./Test2 
Content-type: text/html; charset=utf-8

And Test2: <stdout>: commitBuffer: invalid argument (invalid character)
Run Code Online (Sandbox Code Playgroud)

修改后的代码

/tmp $ ./Test2
Content-type: text/html; charset=utf-8

And ??????? ????????
/tmp $ LANG=C ./Test2 
Content-type: text/html; charset=utf-8

And ??????? ????????
Run Code Online (Sandbox Code Playgroud)