dポイントプレゼントキャンペーン実施中!

Perlでプログラミングしています。

原因不明の改行に悩まされています。
あるスクリプトを通すと2行だった行が1行になります(csvファイル)。

それはさておき、
エディターではちゃんと2行なのにメモ帳で開くと1行です。
エディターはSHIT-JISのようです。

メモ帳の文字コードはなんなのでしょうか?

A 回答 (9件)

え、CGIで動かしてたんですか?


そりゃあ標準出力に余計なもの吐けばエラーになりますね。

状況を整理したいのですが、

・Perlスクリプト(CGI)を実行している環境
・元テキストの由来(あるツールの出力だとか)
・出力結果の受け取り方(ブラウザの画面に表示される? ダウンロードする?)

を明確にできますか?
    • good
    • 0
この回答へのお礼

今回は試す時間が少ないので一度閉め切らさせて頂きます。
すみません。
またよろしくお願いします。
とても参考になりましたのでポイントさせて頂きます。

お礼日時:2007/11/25 23:05

どういう状態になっているのか確認したいので、


以下のコード片を jcode::convert した直後辺りに入れてみて
結果を教えてもらえますか?

my $crcnt = (() = $eachtxt =~ m/\r/g);
my $lfcnt = (() = $eachtxt =~ m/\n/g);
my $crlfcnt = (() = $eachtxt =~ m/\r\n/g);
my @last5 = unpack 'H2'x5, substr($eachtxt, -5);

printf "CR=%d, LF=%d, CRLF=%d, %s\n",$crcnt, $lfcnt, $crlfcnt, join(':', @last5);
    • good
    • 0
この回答へのお礼

再回答ありがとうございます。
試してみましたが、内部エラーが出てだめでした。
文法的には大丈夫のはずなのですが、プログラムを作り変えた
せいかも知れません。

ログイン情報を書き込むルーチンを作り、そこでLocationで
URLに飛ばす仕様にしてみました。


sub do_login {
undef @txt;
undef %cookie;
$cookie{'mynum'} = $mynum;
$cookie{'mypass'} = $mypass;
&print_cookie($cookiename, $cookiedays);

&verify_num($mynum);
&verify_pass($mynum, $mypass);

&read_txt2;
foreach $eachtxt (@txt) {
chomp $eachtxt;
($tonum, $name, $id, $plan, $topass, $month, $submit, $ok, $week, $remain, $tuition, $facility, $text, $admission, $proportion, $course, $ticket, $total, $detail, $premonth, $pretuition, $remark, $login) = split(/,/, $eachtxt);
#$eachtxt =~ s/\x0D\x0A|\x0D|\x0A//g;

if ($tonum eq $mynum) {
$day = substr(&get_date_string,0,11);
#$day =~ tr/-//d;




chomp $day;
$eachtxt = join(',', ($tonum, $name, $id, $plan, $topass, $month, $submit, $ok, $week, $remain, $tuition, $facility, $text, $admission, $proportion, $course, $ticket, $total, $detail, $premonth, $pretuition, $remark, $day));
$eachtxt .= "\r\n";
#my $crcnt = (() = $eachtxt =~ m/\r/g);
#my $lfcnt = (() = $eachtxt =~ m/\n/g);
#my $crlfcnt = (() = $eachtxt =~ m/\r\n/g);
#my @last5 = unpack 'H2'x5, substr($eachtxt, -5);
#print "$crcnt, $lfcnt, $crlfcn";

}
$eachtxt =~ s/\x0A//g;

push @all, $eachtxt;
}
@txt = @all;
&write_txt2;


print "Location: $thisurl?mycmd=read2&mynum=$mynum&mypass=$mypass\n\n";

}

お礼日時:2007/11/20 11:04

>$eachtxt .= "\r\n";


これだと出力時に、CRCRLF つまり、0D0D0A になると思います。
#6の繰り返しになりますが、内部的には、\n は LF(0A)ですが、出力時に CRLF(0D0A)に変換されますので、
$eachtxt .= "\n";
としたら良いという事になると思いますよ。

>$eachtxt .= "\r\n";
>の処理を加えたあと
>$eachtxt =~ s/\x0A//g;
これだと、CR(0D)になってしまって良くない気がするんですが、良かったんですか?
    • good
    • 0
この回答へのお礼

そうですよね。理論的にはおっしゃるとおりだと思います。
それで
$eachtxt .= "\n";
でやってみました。

すると、だめでした。↑が出現し、メモ帳で開くと
2行が1行になってしまいました。

この特定のファイルで起こるこの問題本当に不可解です。

しばらく締め切らないのでまたヒントがあったら教えてください。

お礼日時:2007/11/19 13:22

改行コードについてですが、メモ帳って事は ActivePerl ですよね。



ActivePerlなら、スクリプト内での \n は LF らしいのですが、
ファイルをテキストモードで読み込む場合は CRLF を LF に変換して、
出力時は LF を CRLF に変換するらしいので、
バイナリモードを使わずにテキストファイルを処理する場合は単に \n を改行コードとして扱えば
特に問題は起こらないと思うんですけどね。

>原因不明の改行に悩まされています。
>あるスクリプトを通すと2行だった行が1行になります(csvファイル)。

>$loginのところでおかしい改行が入ってしまいます。

どうおかしいのか、いまいち良く分からないのですが、
1、余計な改行が入ってしまう。
2、入るべき改行が入らない。
3、両方。
どれでしょう?

メモ帳で正しく改行されるのは、CRLF なんで、
入力ファイルをメモ帳で開いて正しく表示されるのなら、そのファイルの改行は CRLF なのでしょう。
で、そのスクリプトを通して出力されたファイルがメモ帳で正しく表示されないのなら、
改行コードが CRLF 以外の物になっている。ただそれだけの事だと思います。

最初に書きましたけど、バイナリモードなら話は別です。
とりあえず、出力されたファイルをバイナリエディタで見てみたらどうでしょう。
    • good
    • 0
この回答へのお礼

もしかしたらできたかも知れません。

おっしゃるとおりバイナリディタとやらで見てみました。
スクリプトを通したときだけODOA(改行)に最後0Aなる文字を発見。

そこで
$eachtxt .= "\r\n";
の処理を加えたあと
$eachtxt =~ s/\x0A//g;
したら、見事大丈夫でした。

$eachtxt .= "\r\n";
をなくしてみたらやっぱり駄目でしたので
なぜか付加しています。

もう少し様子を見て締め切らせて頂きます。
みなさまにとても感謝しております。

お礼日時:2007/11/19 02:06

>以上のスクリプトは誤解受けてしまいますが、エラーが出て


>いろいろ試している過程でつけました。

から予想ですけど、

>#$eachtxt =~ s/\x0D\x0A|\x0D|\x0A//g;

これで改行コードが消えてただけなんじゃないですか?

とりあえず split する前に chomp して、
必要なら、
>#$eachtxt =~ s/\x0D\x0A|\x0D|\x0A//g;
して、その後 \n を付け足せばいいんじゃないですかね。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

理論上、そうなるはずが、いろいろやってみましたが、
駄目でした。

特定のテキストファイルのみ変な文字が入ってしまうとは・・・。

Perlむずかしいですね。こういうことよく起こります。

MySQLに移行するのでそちらに移行すれば解消できると
思いつつ、やはりこの問題クリアしたいです。

お礼日時:2007/11/18 21:48

> $eachtxt =~ s/\r\n/\r/g;


> $eachtxt =~ s/\n/\r/g;

メモ帳が改行として認識できるのは \r \n の並びだけなので、
これを実行して \r にしてしまうと、改行がめちゃくちゃになります。

この回答への補足

以上のスクリプトは誤解受けてしまいますが、エラーが出て
いろいろ試している過程でつけました。
おっしゃるとおり改行はめちゃめちゃになりました。

メモ帳では認識できない改行コードをメモ帳でも認識できる
改行コードに変えればいいはずなのですが・・・。
それを意図しても駄目です。。。

補足日時:2007/11/18 10:40
    • good
    • 0

> あるスクリプトを通すと2行だった行が1行になります



そのスクリプトの処理内容を教えてください。

この回答への補足

回答ありがとうございました。
スクリプト、部分的に示しておきます。いろいろ試している状態です。
ちなみにいろいろこのスクリプトは使いまわしており、そのCSVファイル以外は問題ありません。特定のcsvファイルを通すと変な改行コードが現れてしまいます。

&read_txt2;
foreach $eachtxt (@txt) {

($tonum, $name, $id, $plan, $topass, $month, $submit, $ok, $week, $remain, $tuition, $facility, $text, $admission, $proportion, $course, $ticket, $total, $detail, $premonth, $pretuition, $remark, $login) = split(/,/, $eachtxt);
if ($tonum eq $mynum) {
$login = &get_date_string;
$eachtxt = join(',', ($tonum, $name, $id, $plan, $topass, $month, $submit, $ok, $week, $remain, $tuition, $facility, $text, $admission, $proportion, $course, $ticket, $total, $detail, $premonth, $pretuition, $remark, $login));
&jcode'convert(*eachtxt, $kanjicode);
$eachtxt =~ s/\r\n/\r/g;
$eachtxt =~ s/\n/\r/g;

#$eachtxt =~ s/\x0D\x0A|\x0D|\x0A//g;

}
push @all, $eachtxt;
}
@txt = @all;
&write_txt2;

補足日時:2007/11/17 19:16
    • good
    • 0

文字コードはShift-JISですけれど,スクリプトが改行コード(行末コード)を書き換えているのでしょう。


http://www.atmarkit.co.jp/fwin2k/win2ktips/403eo …
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

たぶん問題はこれだと思います。
ケタずれの可能性もあるので変数の位置を変えてみたりしました。
$loginのところでおかしい改行が入ってしまいます。

お礼日時:2007/11/17 19:21

◇もしかして、単純な事では・・・?



※メモ帳の書式(O)が、右端で折り返す(W)になっていませんか?

間違いでしたら、読み飛ばしてくださいね・・
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

右端で折りかえすが問題ではないようです。

>間違いでしたら、読み飛ばしてくださいね・

ご解答頂けてとても参考になりました。

お礼日時:2007/11/17 19:23

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


このQ&Aを見た人がよく見るQ&A