カレッヂ |
質問者 ひろ
投稿日 2/19(月) 21:31:46
「プロセス番号の意味」のスレッドにてお世話になりました。 処理の流れ等はそちらと同じですので、詳しい背景は省略されて頂きます。 以下の状態で、どんな原因が考えられるのかを教えて頂きたいと思います。 入力フォームから送られてきたデータを、CGI(A)にてテキストファイルに書き出します。 この時点でのテキストファイルにはデータの欠損は認められません。 (この時点のデータを別ファイルに書き出して確認しました) このテキストファイルをCGI(B)にて読み出し、配列に格納してsendmailしています。 この時にデータ内の文字が「消失している事」がありました。 いつもではありません。 現在確認できたのは漢字の「助」(人名の一部です)と カタカナの「カ」の文字です。 これまで同じスクリプトで処理を行ってきましたが、 こういった「消失」はありませんでした。 (1)読み込んで配列に格納する所と、(2)その配列を書き出す所の スクリプトを下に載せておきますのでお願い致します。 データの内容は、住所・氏名・電話番号・メールアドレス等 注文する際に必要となる項目です。 また、CGI(A)からCGI(B)への間に特に処理はあてていません。 --------------------- require 'jcode.pl'; -------(1)--------- open (FILE,"data.txt"); while (<FILE>) { chomp if /\n$/; ($name, $value) = split(/=/); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; $name =~ tr/+/ /; $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; &jcode'convert(*name,'sjis'); &jcode'convert(*value,'sjis'); $name =~ s/\s*//g; $value =~ s/\s*//g; if ($value =~ /\r\n/) { $value =~ s/\r\n//g; } elsif ($value =~ /\r/) { $value =~ s/\r/\n/g; } if ($name =~ /^email/i || $name =~ /^e\-mail/i) { $value =~ s/ / /g; if ($value =~ / / || $value =~ /;/) { $value = ""; } $email = $value; } push(@DATA_N,$name); push(@DATA_V,$value); } close(FILE); --------(2)---------- sub sendmail { if (!(open(OUT,"| $sendmail -t"))) { &error('システム異常','申し訳ありませんが何らかの原因で処理できません.'); } $count = @DATA_N; foreach (0..$count-1) { if ($DATA_V[$_] =~ /\n/) { &jis("$DATA_N[$_] =\n\n$DATA_V[$_]\n"); print OUT "$msg\n"; } else { &jis("$DATA_N[$_] = $DATA_V[$_]"); print OUT "$msg\n"; } } close(OUT); ------------------ sub jis { $msg = $_[0]; &jcode'convert(*msg, 'jis'); } ------------------ 何故文字が消えたり消えなかったりするのでしょうか? どこかおかしいですか? |
回答者 さくら
[削除]
投稿日 2/20(火) 02:48:52
コードの一部を拝見しました。 やや冗長な感じも致しますが、それはさておき今回の質問についてですが、 文字が失われたしまうようなコードは、特に無いように感じます。 一つづつ確認して見る必要が有るのではないでしょうか。 1. 同じデータを送った場合、常にデータが失われるのか? (確認されている 助とカについては失われたときと同じデータを送って確認して見る) 2. jcode.plのコード変換時について確認して見る 3. コードブロックを終了する度に、print して見る、できれば、ファイルに書き出す このような手順で確認していくのはどうでしょうか。 1.についてですが はっきり、データが失われる事を確認しないと、テストを繰り返すたびに結果が異なるのでは、コードをいじっても、完全に修正されたか確認が難しい。 2.についてですが jcode.plを疑うわけではないのですが、バージョンを確認して見ましょう 必ず最新のものを使おう。現在はv2.13です。 s-jisに変換していますが、s-jis の2バイト目はasciiと重なる事も覚えておこう。 この程度の事でjcode.plが混乱するとは思えないが、入力された文字コードを 指定する事によってより確実なコード変換が行なえることもある。 (jcode.plにある getcode() というメソッドで送信された文字コードを取得できる) 私自身は、下記のようにして送信データを処理しています。 たぶん、最も確実だと思われる方法で行なっている(私が勝手に思っているのですが) 送信されたデータは必ずeucに変換している、そして必要に応じてjis s-jisに変換する 事にしている。 まず、form に追加する <input type="hidden" name="code" value="日"> これは、送信されたデータの文字コードを確実に識別する為に使う。 スクリプト中で、"日" を $code に代入したとする。 $code = jcode::getcode(\$code); #perl5ではこう書ける。 これで左辺の$codeには、文字コードが格納された(jis,s-jis,euc など) jcode::convert(\$value, 'euc', $code, 'z'); これは、$valueの値をeucに変換する、元の文字コードは$codeである、 'z'オプションおつけると半角カナを全角カナに変換する。 (半角カナは1バイトで、非常に厄介な存在なので私は必ず、全角に変換している) sendmail に渡す前にjisに変換しているところも上記のように使える。 又は、UNIXユーティリティのnkfがあれば、nkfにパイプすれば良い。 open (OUT, "| $nkf -j | $sendmail -t") こうすると、nkfでjisに変換されて、sendmail に送られる。($nkfにnkfのパスが入っているものとする。) 3.について urlデコードや、文字コード変換等は、CGI(A)に移して見る等も有効かもしれない。 つまり、デコードして、文字コード変換してからファイルに書きこみすることによって そこまでの処理が正しく行なわれているか確認できる。 CGI(B)で行なわなければいけない所は、しょうがないので、途中に別のファイルを作成 して書き込みしてみる。 こうして、原因の場所を特定して行く事になる。 jcode.plの関係をたくさん書いたのですが、なんとなく文字消失とjcode.plの処理に 何らかの関係があるような気がしたものですから。 ちがったらゴメンナサイ! 最後にjcode.pl の使い方について日本語で解説しているページのurlを掲載しておきます。 http://www.mikeneko.ne.jp/~lab/kcode/jcode.html |
質問者 ひろ
[削除]
投稿日 2/20(火) 14:33:03
さくらさんありがとうございます。 え〜、現在もまだ原因解析中なんですが途中経過と判明した事を。 jcode.plのバージョンですが、これまで使用していたものを確認してみたところ $rcsid = q$Id: jcode.pl,v 2.8 1998/09/23 17:22:55 utashiro Exp $; と書かれたものでした。v2.8? なにやら変ですね・・・ 現在は最新版(?)の v 2.13 2000/09/29 16:10:05 にて試験を行っています。 再度書きますが、CGI(A)にて入力フォームからのデータをデコードし、 data.txtへ書き出します。 この時点でのデータ内容は正常です。 ちなみにデータは name = あああああ\n address = いいいいいい\n といった形で格納されています。 このファイルをCGI(B)で読込み、上記のスクリプトで「もう一度」デコードを かけている事により、内容がおかしくなっている事が確認されました。 「助」「カ」を含む、同じデータを何度送ってもそこだけおかしくなります。 新たに「朝」という漢字が「ト」に変換されてしまうのも見つかりました。 という事で引き続き解析を行います。 |
質問者 ひろ
[削除]
投稿日 2/20(火) 17:02:55
引き続き途中経過です。 CGI(B)にて、data.txtを開いて読み込み、 そのまま別のファイルに書出した時にはデータは完全なままでした。 ところが ($name, $value) = split(/=/); して print FILE "$name$value\n"; と書き出してみると name ○○ 大● 釶辣煖瘤a タナカ ○○○○ となってしまいました。●部分が「助」です。 splitの使い方間違ってますか? |
質問者 ひろ
[削除]
投稿日 2/20(火) 18:56:51
すみません。 結局理由は分からなかったのですが、 変にsplit等の処理をせずにファイル内容をそのままsendmailに出力する事で 解決しました。 さくらさん、それでも私の知識が増えましたのでお礼申し上げます。 |
このページは終了したので返信(回答)は書きこめません
Web裏技 |