• 締切済み

改行コードが勝手に

はじめまして。perl初心者です。 見よう見まねでやりはじめたのですが。どうしてもわからないことがあります。 数十行ぐらいのテキストファイルがあるのですが、その中を訂正するcgiを作成しています。 htmlからそのファイル名を指定して、 open (DATA, "$file1"); #$file1がファイル名 として htmlのテキストエリアに表示して訂正し、それをさらに別のcgiで書き込むようにしています。 print "<form ACTION=\"hensyuu.cgi\" METHOD=\"POST\">\n; print "<textarea name=\"MSG\" cols=100 rows=30>\n"; foreach $gyou ( < DATA > ) { print $gyou; } print "</textarea>\n"; print "<input type=\"submit\" value=\"書込\">\n"; print "</form>\n"; hensyuu.cgiは open ( DATA,">>$file1" ); #ここでtextareaの内容を読み込み print DATA "$in{MSG}"; close ( DATA ); 編集したデータを見ると、各行ごとになぜか空白行が入ってしまいます。 バイナリエディタで見ると通常の0D0Aの前に0Dが追加され、0D0D0Aとなっているために そうなっていると思われます。 これってそういうものなのでしょうか。 それとも根本的にこんなやり方は間違っているのでしょうか。 ご教授のほど、よろしくお願いします。

  • Perl
  • 回答数2
  • ありがとう数2

みんなの回答

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

LFの処理系でCRLFのファイルをそのまま読み込み:CRLFのまま残る →LF改行のファイルだとして、CRLF改行に変換:もとのCRはそのまま、LFがCRLFに変換される →CRCRLF ということだと思われます。 で、CRLFが出てくるのでWindowsを使っていると思いますが ・CGIを実行しているのはどこ? ・出力ファイルはどこにできるの?WindowsPC上でなかったらどうやってコピーしてくるの? Windows → Linux等のunix系で動作しているhttpサーバーで CGIを実行 →ファイルをアップロード(このときはバイナリーモード) → サーバー上にファイルが作成 →ftpでPC へ(このときはテキストモード) ってなってませんか? 対処方の一つは、どこかでCRを取り除くことです。 foreach $gyou ( < DATA > ) { $gyou =~ s/\r//g; #←とか print $gyou; }

marusu_jp
質問者

お礼

回答ありがとうございます

  • asciiz
  • ベストアンサー率70% (6632/9395)
回答No.1

改行は論理的には「\n」ひとつなんですが、環境によって実際の文字コードが違ってきます。 Unix系→LF(0x0A) Windows系→CR,LF(0x0D,0x0A) Macintosh→CR(0x0D) プログラム単体で動くのでいいんだったら、 ・一行読み込み ・改行を削除(chop($line); ) ・文字列処理 ・改行付きで出力(print $line, "\n";) でいいんですが。 WebサーバはUnix系だけども、表示したブラウザはWindowsだったりMacだったりするので困るのです…。 ---- 私が過去に作ったスクリプトでは、こんな乱暴な処理をしてました。 $buffer に全行読み込み後、 $buffer =~ s/(%0D|%0A)/&/g; # CR / LF は全て「&」文字に置換 $buffer =~ s/&+/&/g; # 連続&をまとめる $buffer =~ tr/&/\n/; # &を1改行とする これでも良かったのは、扱うデータが特定のCSVファイルだったため、 ・「&」文字が出てこない(自分のデータファイルでは) ・空行は存在しない という条件があったからです。 「&」文字ではなく、「%01 」みたいな文字データに出てこない(漢字等であっても)文字(コード)に置換するのが良いかも知れません。 空行の問題が解決しませんが…。 ---- あるいはどうせ3パターンなので、$bufferに読み込み後、 $buffer =~ s/\r\r\n/\n/g; $buffer =~ s/\r\n/\n/g; $buffer =~ s/\r/\n/g; と流してしてしまってもいいのかも?

marusu_jp
質問者

お礼

回答ありがとうございます。 自己解決しました。 ご指摘いただいたとおり、各行を表示する前や その後のファイル書込み前に改行コードを削除してみましたが 変化ありませんでした。 ただそこで気づいたのが、ファイルの最後の改行だけは削除されています。 ということは、変数MSGが複数行のデータではなく 1行のデータとして認識されているのでは? と考えました。 そこでファイル書込み前に @kakikomi = split ( /\n/, $in{MSG} ); としてデータを改行コードで配列に変換し、 書込みのときに foreach $a = ( @kakikomi ) { chop ( $a ); print DATA "$a\n"; } としたところ、うまくいけました。 自己解決したとはいうものの、kmeeさん、asciizさんのご指摘がなければ 解決できなかったところです。 本当にありがとうございました。

関連するQ&A

  • TEXTAREAで改行するとついてくるゴミコード

    自分で作成したCGIで送信されてきたフォームデータを 取得し、テキストファイルに出力するような処理をやってまして、 その送信されるデータにはTEXTAREAで入力されたデータもあります。 CGIの処理後に出力されたファイルをテキストエディタで開こうしたら、 テキストエディタでオープン不正であるようなメッセージが表示されました。 自分でもその原因についてバイナリエディタで調べたところ、 TEXTAREAで改行されたところに不正なゴミコードが混ざっているようでした。 改行コードは16進数でいうと「0D0A」のはずですが、バイナリファイルで みたところ改行部分が「0D0D0A」となっているようで、どうやら「0D」の余計な コードがテキストエディタで開いた時、エラーを発生させている原因となってるようです。 CGIの処理内でこの「0D」コードを削除する処理をいれるのもいいんですが、 なにか簡単にこの「0D」というゴミコードを取り除きたいのですが、 ナニかいい方法ないでしょうか?

    • ベストアンサー
    • CGI
  • 改行コードについて

    ファイルの文字コードはutf-8で改行コードはLFです。 メール送信時にメール文面の一部にいれるテキストを mysqlに保存しています。 メール送信のソース内でデータを読み込み送信までは できているのですが改行コードを変換したく $msg = str_replace("\r\n", "\n", $msg); とやってみましたが改行されず普通に\r\nと表示され うまく変換ができません。 いろいろと試した結果以下のソースでは正常に改行されました。 $msg = str_replace("\\r\\n", "\n", $msg); メール送信前にデバッグでしてみましたが読み込むデータの 改行部分は\r\nとなっているのは確認済みです。 \を多くつければ改行はできるようなのですがこれは仕様なの でしょうか? またmysqlに入れてあるデータはフォームから入力し登録 しているのですがLFの改行コードは\nなので登録時に\r\nではなく \nと変換してからmysqlに登録するのがいいものなのでしょうか?

    • 締切済み
    • PHP
  • javascriptでCGIに値を渡したいのですが、テキストエリアの値で改行コードが消えてしまいます。教えて下さい。

    javascriptでCGIに値を渡したいのですが、テキストエリアの値で改行コードが消えてしまいます。教えて下さい。 別窓ページにてtest.cgiを呼び出し、そのCGIに値を渡したいのですが、 一応値はテキスト形式で渡せるのですが、テキストエリアで入力したものの 改行コードが消えてしまいます。何か良い方法があれば、教えて下さい。 <FORM name="test" ACTION="javascript:test_window_open('/cgi-bin/test.cgi?bikou='+document.test.bikou.value);"> : : <TEXTAREA rows="8" cols="50" name="bikou"></TEXTAREA>

  • 配列のデータから改行だけを取り除いて上書きしたい

    いつもお世話になっています。 CGIで現在下記のようなファイルがあります。 【sample.cgi】 1<>2<>3<>4<>5<> 6<>7<> これを下記のスクリプトで呼び出し配列に入れます。open(IN,"./sample.cgi"); @DATA = <IN>; close(IN); @data = split(/<>/,$DATA[0]); @N_DATA=(); unshift(@N_DATA,"$data[1]<>$data[2]<>$data[3]<>$data[4]<>$data[5]<>$data[6]<>$data[7]<>"); open(OUT,">./sample.cgi") or &error('書き込み失敗'); print OUT @N_DATA; close(OUT); しかし実行結果は改行が残ったままで、どうにか 1<>2<>3<>4<>5<>6<>7<> という形で出力したいのですがどのように変更を行えば宜しいでしょうか。 恐らく「unshift」の部分が行を追加していっていると思うのですが、printなどで出力するとsample.cgiの中身が空になってしまい・・・。 「読み込むデータに改行があった場合は改行を削除して読み込む」という動作をさせたいのですが・・・。 何卒よろしくお願い致します。

    • ベストアンサー
    • CGI
  • テキストエリアにテキストファイルを改行コードごと読み出すには

    ただ今勉強中のCGIを使って、テキストファイルの編集・上書き保存をテキストエリアから行いたいのですが、テキストエリアに読み込む時に改行コードが読み込めないためか、最後の一行しか表示できません。どのようにすると、改行コードを含めて編集できるのでしょうか? その「できないコード(サブルーチン)」は↓になります。 $commentfile = "comment.txt"; ■ 読み出し sub read_commentfile { local($masg); open(IN, $commentfile); while (<IN>) {$masg = join('',$_);        $massage = $masg; } close(IN); } ■ コメントの編集画面 sub comment { local($html); &read_commentfile; #HTML作成 $html = << "EOM"; <html lang="ja"> <head> <meta http-equiv="content-type" content="text/html; charset=$charset"> <title>コメントの編集</title> </head> <body> <form action="$self" method=post> <input type=hidden name=mode value="savecomment"> <hr> コメント<br> <textarea name=masg cols=40 rows=4>$massage</textarea> <br> <input type=submit value=" 更新 "> </form> <hr> </body> </html> EOM &print_html($html); } ■ 上書き保存 sub savecomment { local(@text); push(@text, "$FORM{'masg'}\n"); open(OUT, ">$commentfile"); print OUT @text; close(OUT); } 本来でしたら、ファイルのロック・解除、表ダグ、パスワード等の記述もあるのですが、省いてあります。 よろしくお願い致します。

    • ベストアンサー
    • CGI
  • textareaの入力データで無駄な改行が…

    textareaでデータ入力し、perlで拾うと無駄に改行が入ってしまいます。 <textarea name="textarea_data"> a a a </textarea> これをPerlで拾って表示させると a a a と表示されてしまいます。 改行が無駄に一つ入ってしまっているのですが、考えられる原因は何でしょうか? print "$FORM{'textarea_data'}"; で表示させています。\n等は入れていません。

    • ベストアンサー
    • Perl
  • CGIROOMさんのデータベース機能について、管理者と連絡取りたい

    CGIROOMさんのデータベース機能について、管理者と連絡取りたい。 また、簡易高機能検索専用データベース ソート版(http://cgiroom.nu/list/database/database2s/)と、database.cgi用 データエディタ(http://cgiroom.nu/list/database/dataedit/index.htm)を併用して利用しているのですが、データファイルの容量が300k以上になると、エラーが表示されてしまうのですが、これを解除する方法をどなたか教えていただけませんか? ソースデータ if($FORM{'cmd'} eq "edit" && $FORM{'line'}){ &error('300k以上あるデータは修正できません') if -s $FILE > 01234567; open(IN,$FILE) || &error('データファイルを開けません'); @data = <IN>; close(IN); if($FORM{'write'}){ &error('行指定が不正です') if $FORM{'line'} =~ /\D/; $data[$FORM{'line'} - 1] = join("\t",@line[1..$#line],"\n"); open(OUT,">".$FILE)|| &error('データファイルを更新できません'); print OUT @data; close(OUT); &msg('更新しました'); } @data = split(/\t/,"\t".$data[$FORM{'line'} - 1]); &error('指定されたデータは存在しません') unless @data; open(HTML,$FORM)||&error('フォームファイルを開けません'); read(HTML,$html,-s HTML); close(HTML); $html =~ s/__(cmd|line)__/$FORM{$1}/g; $html =~ s/__data(\d+)([a-zA-Z]*)__/&tag($data[$1],$2)/eg; &html(\$html); }elsif($FORM{'cmd'} eq "new"){ &error('300k以上あるデータは修正できません') if -s $FILE > 01234567; if($FORM{'write'}){ if($unshift){ open(IN,$FILE) || &error('データファイルを開けません'); @data = <IN>; close(IN); open(OUT,">".$FILE)|| &error('データファイルを更新できません'); print OUT join("\t",@line[1..$#line],"\n"),@data; close(OUT); }else{ open(OUT,">>".$FILE)|| &error('データファイルを更新できません'); print OUT join("\t",@line[1..$#line],"\n"); close(OUT); } &msg('データを追加しました'); } open(HTML,$FORM)||&error('フォームファイルを開けません'); read(HTML,$html,-s HTML); close(HTML); $html =~ s/__cmd__/$FORM{'cmd'}/g; $html =~ s/__data\d+[a-zA-Z]*__//g; &html(\$html); }elsif($FORM{'cmd'} eq "delete" && $FORM{'line'}){ &error('300k以上あるデータは修正できません') if -s $FILE > 01234567; &error('行指定が不正です') if $FORM{'line'} =~ /\D/; open(IN,$FILE) || &error('データファイルを開けません'); @data = <IN>; close(IN); &error('指定されたデータは存在しません') unless $data[$FORM{'line'} - 1]; undef $data[$FORM{'line'} - 1]; open(OUT,">".$FILE)|| &error('データファイルを更新できません'); print OUT @data; close(OUT); &msg('指定されたデータを削除しました'); } どこを修正すればいいのでしょうか?

  • リンククリックでデータを送信。

    cgiでログファイルを開き、タイトル行だけを表示させています。(行数分) そのタイトルをリンクとして、クリックしたら全文が表示されるようにしたいと思い、以下のようにしてみました。 print "<TD WIDTH=200><A HREF='top_search.cgi'><INPUT TYPE=HIDDEN NAME=GYOU VALUE=$i>$FORM{'TITLE'}</A></TD>\n"; やはり、データの送信はボタン(submit)でないとダメでしょうか? リンクでデータの送信をするのはできませんか? よろしくお願いします。

    • ベストアンサー
    • CGI
  • textarea へ、改行させたいテキストデータを書き込むには?

    Perlのprint命令では、print '(1)aaaa <BR>(2)bbbb',"\n"; というように、改行させたい箇所に<BR>を挿入すれば改行させられるとおもいます。ところが、print "<textarea> xxx </textarea>" として、CGIで複数行入力領域を書いたときは、xxxのなかに挿入した<BR>はそのまま文字として表示されてしまいます。  改行させるにはどうしたらいいのでしょうか?  どなたか(ひきつづき^^;;)、御教示をいただければ幸いです。

    • ベストアンサー
    • Perl
  • 変数の表示の仕方(改行の扱い)

    perl初心者です。よろしくお願いします。 ひとつの変数で、print関数での表示とテキストエリアでの表示を しようとしているのですが、改行の扱いに困っています。 テキストエリアで<br>を表示させないようにすると、print関数の 方の改行がなくなるし、print関数の方に改行させると、テキスト エリアで<br>が表示されるし・・・。 print関数で改行、テキストエリアでは<br>が出ずに改行という 風にしたいのですが、どなたかご教授していただけませんか? よろしくお願いします。 #!/usr/local/bin/perl use strict; #データファイル my $datafile='./data.dat'; #ライブラリの読み込み require './jcode.pl'; my $input; #フォームデータの読み込み if ($ENV{REQUEST_METHOD} eq "POST"){ read (STDIN,$input,$ENV{CONTENT_LENGTH}); }else{ $input=$ENV{QUERY_STRING}; } #フォームデータのデコード my %form = (); my @pairs = split(/&/, $input); foreach my $pair ( @pairs ){ my( $name, $value ) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("H2", $1)/eg; #SJISコード変換 &jcode::convert(\$value, 'sjis'); $value =~ s/\r\n/<br>/g; $value =~ s/\r/<br>/g; $value =~ s/\n/<br>/g; $form{$name} = $value; } #データのオープン open(DAT,"+<$datafile"); flock(DAT, 2); #ファイル読み込み my $line = <DAT>; for ( split /\t/ , $line ) { my( $key , $value ) = $_ =~ /^([^=]*)=(.*)$/; #フォームデータの上書き $form{$key} ||= $value; } #データの書き込みとクローズ seek(DAT,0,0); $line = ''; while (my($key,$value) = each %form) { $line .= "${key}=${value}\t"; } print DAT $line; close(DAT); &header; print $form{A}; print "<br>"; print $form{B}; print "<br>"; print $form{C}; print "<br>"; print <<EOM; <b>[内容確認]</b> <form action="new.cgi" method="POST"> <INPUT TYPE="text" SIZE="27" name="A" value="$form{A}"><br> <INPUT TYPE="text" SIZE="90" name="B" value="$form{B}"><br> <TEXTAREA name="C" ROWS="2" COLS="27">$form{C}</TEXTAREA><br> <input type="submit" value="上記内容で送信"> </form> <br> </body> </html> EOM exit; #----------------------------------------------------------------------------------- # HTMLヘッダー #----------------------------------------------------------------------------------- 割愛

    • ベストアンサー
    • Perl

専門家に質問してみよう