
はじめまして。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となっているために
そうなっていると思われます。
これってそういうものなのでしょうか。
それとも根本的にこんなやり方は間違っているのでしょうか。
ご教授のほど、よろしくお願いします。
A 回答 (2件)
- 最新から表示
- 回答順に表示
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;
}
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;
と流してしてしまってもいいのかも?
回答ありがとうございます。
自己解決しました。
ご指摘いただいたとおり、各行を表示する前や
その後のファイル書込み前に改行コードを削除してみましたが
変化ありませんでした。
ただそこで気づいたのが、ファイルの最後の改行だけは削除されています。
ということは、変数MSGが複数行のデータではなく
1行のデータとして認識されているのでは?
と考えました。
そこでファイル書込み前に
@kakikomi = split ( /\n/, $in{MSG} );
としてデータを改行コードで配列に変換し、
書込みのときに
foreach $a = ( @kakikomi )
{
chop ( $a );
print DATA "$a\n";
}
としたところ、うまくいけました。
自己解決したとはいうものの、kmeeさん、asciizさんのご指摘がなければ
解決できなかったところです。
本当にありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
- PHP PHPでCookieを使った訪問回数について 1 2023/05/28 14:10
- PHP if(preg_match("/[^0-9]/",$gu_d)){意味を教えてください。 1 2022/05/06 05:37
- PHP PHP MySQLに画像を直接保存 2 2022/06/05 11:50
- CGI perlで書いたcgiでsqliteの使い方を教えてください 2 2023/05/08 21:29
- Excel(エクセル) PHPプログラムをエクセルに張り付けると検索ボックスがでてくる! 3 2022/05/08 07:10
- PHP htmlspecialcharsが機能していないです。 バグですか? 1 2022/04/05 01:22
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
- PHP PHP MySql 画像を取得 1 2022/06/04 14:05
- PHP PHPで画像の渡しが上手く行きません。 1 2023/02/02 09:39
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
perlでファイル内の文字列を置...
-
where can I buy snowbord in t...
-
die関数のエラー出力先について
-
Perlで特定行から特定行までを...
-
ExcelをCSV書き出す場合のシー...
-
VBAでCSVファイルを途中行まで...
-
drtファイルはどうしたら開...
-
MATLAB グローバル変数の宣言
-
sprintfについて
-
vba dir の相対パス
-
fgets で値が取得できない
-
Perlの変数に文字数制限(容量...
-
ファイル名と更新日付の取得に...
-
window.open でのファイル指定方法
-
ディレクトリー内のリスト出力...
-
Perl-CGI で排他制御はどうすれ...
-
Windowsで複数のファイルを同じ...
-
ファイル名を複数個配列で確保...
-
ファイル全てを .xlsm に変更し...
-
文字化け
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
close()で例外が投げられる理由
-
perlのflock関数でロックをかけ...
-
改行コードが勝手に
-
where can I buy snowbord in t...
-
ファイルのロックについて
-
perlで複数のファイルの処理に...
-
perlを用いた特定文字列間の抽...
-
変数を使ってファイル名を自分...
-
open中のファイルをrename
-
文字列比較がどうしてもできま...
-
データの入れ替え処理が巧くで...
-
perlで大容量CSVのsort方法につ...
-
テキストファイルの本文中に行...
-
初歩的な質問で恐縮です。
-
パイプをopenして/usr/bin/grep...
-
perlでのスキンの利用方法
-
ログに記録又は読み出す際、最...
-
Perlのファイルオープン時...
-
Perlでハードウェア制御?
-
perlでファイル内の文字列を置...
おすすめ情報