EUCとSJIS
[上に]
[前に]
[次に]
snow
2000/02/16(水) 11:13:57
文字コードについて教えてください。
CGIプログラムをUNIX上で作成している(EUC)のですが、その中でHTMLファイル出力をさせています。その際、HTML出力部分のソースのみSJISでUNIXに取りこんでコンパイルしているのですが、UNIX上では全てEUCにして表示のみSJISにすることはできるのでしょうか?
(meta で SJISを指定してもNG?)
コウノトリ
2000/02/16(水) 11:39:19
取り込んだHTMLを「そのまま」吐き出すなら、現状のままでOKです。
CGI中に埋め込んだ文字列を追加するなどで加工する場合は、文字コードが混在して化けることがあります。
(それ以前に加工に失敗することもある)
snow
2000/02/16(水) 19:37:39
コウノトリさん、ありがとうございます。
CGIでの結果によって、HTML上に表示する文字列を変えようとしているので、今は文字化けしてしまっています。こういった場合は、普通どのような処理をしておけばよいのでしょうか?
saka
2000/02/16(水) 23:49:43
日本語の処理は、ここを参考にしてみてください。
http://www.tohoho-web.com/wwwperl4.htm#Japanese
通常は
sjis -> euc -> sjis
という様なを変換して処理する事になると思います。
私は、CGIの中で直接sjisの漢字を操作したりしてますが..
通常なら変換して処理した方がやり易いと思います。
B-Cus
2000/02/16(水) 23:50:55
全部 EUC にするのが一番簡単。あるいは、SJIS の HTML データを
いじくる必要がなければ、
FILE *nkfout;
nkfout = popen("/usr/local/bin/nkf -s","w");
fprintf(nkfout,"%s",buf);
で、nkf に全部任せるとか。それなりの負荷はかかりますけど。
ところで、perl で言うところの
open(STDOUT,"|/usr/local/bin/nkf -s");
相当の処理 (標準出力に出力すれば、nkf を経由する)って
C ではどうやるんでしょう?
stdio ライブラリだけでできる?
stdout を fclose(3) して pipe(2) して fdopen(3)?
pipe(2) して stdout を fclose(3) して dup(2) して fdopen(3)?
# ↑うそくせ〜
Hanhan4
[E-Mail]
2000/02/17(木) 23:25:17
> ところで、perl で言うところの
> open(STDOUT,"|/usr/local/bin/nkf -s");
> 相当の処理 (標準出力に出力すれば、nkf を経由する)って
> C ではどうやるんでしょう?
stdio でよければ popen() を使います。
これは /bin/sh を起動するので UNIX ローカルで使う分には
便利ですが,WWW プログラミングで使うのは要注意です。
/bin/sh を避けたいのならば B-Cus さんが見当を付けている
とおりで pipe(), fork(), exec(), dup(), open(), close()
あたりを駆使します。
ここらへんのことはアスキーの
「UNIX システムコール・プログラミング」に出ています。
ちょっと古い本ですが,UNIX 上のプログラミングの
理解に役立つでしょう。
storms
2000/02/19(土) 00:47:38
> ところで、perl で言うところの
> open(STDOUT,"|/usr/local/bin/nkf -s");
> 相当の処理 (標準出力に出力すれば、nkf を経由する)って
> C ではどうやるんでしょう?
stdioだけじゃ無理
運が良ければ/dev/fd+freopenで何とかなる、移植性悪いがFILE構造体を弄るよりはまし。
B-Cus
2000/02/19(土) 01:37:44
> 運が良ければ/dev/fd+freopenで何とかなる
これを試してみたんですが、全然わからなかったので
早々にギブアップ。結局まともな方法としては、
fork/exec から自前でやらなきゃダメってことですね。
別に今必要なわけではないので、今後の課題としておきます。
storms
2000/02/19(土) 14:18:36
こんな感じ。
しかし、ここって自信たっぷりに嘘教える人が多いね。
#include <stdio.h>
main()
{
FILE *p;
char s[] = "/dev/fd/xx";
int i;
if(!(p = popen("cat -n", "w")))
perror("popen"), exit(1);
snprintf(s, sizeof(s) - 1 , "/dev/fd/%d", fileno(p));
if(!freopen(s, "w", stdout))
perror(s), exit(1);
for(i = 0; i < 10; i++)
printf("%c\n", 'a' + i);
fclose(stdout);
pclose(p);
}
Hanhan4
[E-Mail]
2000/02/19(土) 18:12:33
ああ,わかった。storms さんは「必要とされている条件は
『標準出力』だから
fp = popen(...);
fprintf(fp, ..);
ではダメだ」とおっしゃるのですね。なるほど。うむう。
私にしてみれば stdout も fp も FILE * の一つなので
「同じじゃん」ということであのように書きました。
うかつだったかな。
どーしても stdout じゃなきゃダメ,fprintf(fp, ...) なんか
許せないということでしたら,これはどうでしょう?
*stdout = *fp;
printf(...);
# われながら屁理屈...
# こういうことをしていいものかどうかも自信がない。
B-Cus
2000/02/19(土) 23:55:15
ん〜、なるほど。/dev/fd/、*stdout=*fp どちらも
Solaris,FreeBSD でうまく動きました。
ディスクリプタ x へ出力 (入力も) するのと
/dev/fd/x へ出力するのは等価なわけですね 。
> # こういうことをしていいものかどうかも自信がない。
どうなんですかね。素人目には問題ないように
思えますが、もちろん根拠ナシ。
storms
2000/02/20(日) 00:13:03
> *stdout = *fp;
> printf(...);
却下
http://www.catnet.ne.jp/~kouno/c_faq/c12.html#33
http://www.catnet.ne.jp/~kouno/c_faq/c12.html#34
B-Cus
2000/02/20(日) 00:25:30
う、C FAQ を調べるのをすっかり忘れてた。
> 却下
その理由をご存知ですか? 移植性の問題?
storms
2000/02/20(日) 00:59:31
> その理由をご存知ですか? 移植性の問題?
ドキュメントで公開されていない構造体に依存してはいけない。
(この場合は構造体のサイズ)
stdlibのユーザに見える構造体と内部で使用している構造体が
同一と言う保証は無い。
例えばユーザみえは
typedef struct {
....
} FILE;
stdlibの内部では
struct internal_file_t {
FILE fp;
...
}
storms
2000/02/20(日) 16:48:43
> (この場合は構造体のサイズ)
< (この場合は構造体のサイズおよび構造)
致命的な例
typedef struct file_t {
struct file_t *next;
...
} FILE;
このようにFILE構造体がリンクリストで管理されていて、新規にオープンされたファイル(fp)が
root => stdin => stdout => stderr => fp
となるとする
*stdout = *fp
などすると
root => stdin => fp
とリンクリストが破壊される。
fclose(stdout)した後で
*stdout = *fp
は論外。
B-Cus
2000/02/20(日) 18:07:59
なるほど。ユーザに許されているのは FILE へのポインタを
stdio ライブラリ {から受け取る,に渡す} ことだけであって、
うかつに内部を触ると stdio の実装によっては動かなくなる
かもしれんぞ、ということですね。
ありがとうございました。
[上に]
[前に]
[次に]