Perlで数が正しくファイルに読み書き出せません

このQ&Aのポイント
  • Perlで300の数を読み書きした際、一部の数が正しく読み出せない問題について詳しく説明します。
  • Perlで数を読み書きする際に、特定の値(10、26、266、282)が正しく読み出せない問題が発生します。
  • Perlでファイルに数を書き込む際、特定の値(10、26、266、282)が正しく書き込めない問題が発生します。
回答を見る
  • ベストアンサー

Perlで数が正しくファイルに読み書き出せません

Perlで、下のように300の数を読み書きしたところ、 10、26、266、282 だけ正しく読み出せません。なぜですか? open (FRED,"+<test"); $pack_format = "I"; $pack_length=length pack($pack_format,0); for ($n=0;$n<300;$n++){ $age=$n; seek(FRED,$pack_length*$n,0); print FRED pack($pack_format,$age); } for ($n=0;$n<300;$n++){ seek(FRED,$pack_length*$n,0); $qqq=read (FRED,$buf,$pack_length); $age=unpack $pack_format,$buf; print "/$n/$age/$qqq/\n"; }

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

質問者が選んだベストアンサー

  • ベストアンサー
  • leaz024
  • ベストアンサー率75% (398/526)
回答No.1

環境が分からないので完全に再現させることはできませんでしたが、まず間違いなくバイナリデータをテキストモードで扱っているのが原因でしょう。 open の後に、 binmode FRED; を入れてください。

参考URL:
http://tohoho.wakusei.ne.jp/wwwperl2.htm#binmode
wildcat888
質問者

お礼

>まず間違いなくバイナリデータをテキストモードで扱っているのが原因でしょう。 全くそのとおりのようです。 >open の後に、 >binmode FRED; を入れたら、期待どおりに動作しました。 さっそくありがとうございました。 数時間、いろいろやっても解決できませんでした。 大変たすかりました。

関連するQ&A

  • Perlで画像のサイズ取得する方法

    URL指定で画像サイズの取得が出来ません。 何方かご教授お願いします。 悲しいことにレンタルサーバーにはimage::magickがインストールされていないので使えません。 ----perl---- #!/usr/bin/perl $FileName = "http://i.yimg.jp/images/main11.gif"; ( $format, $width, $height ) = &GetImageSize( $FileName ); print "Content-type: text/html\n\n"; print <<"HTML"; <META http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <BR> $width x $height <br> <IMG src="$FileName" border="0"> HTML sub GetImageSize{ my ( $IMG, $in ) = @_; my ( %SHT, %LNG ); my ( $buf, $mark, $type, $f_size, $width, $height ); my ( $TAG, $TYPE, $COUNT, $V_OFFSET, $PK, $ENTRY, $Exif_IFD ); my ( $endian, $dummy1, $dummy2, $dummy, $EOI, $APP1, $length, $exif ); my ( $format, $offset, $line, $CODE, $jfif ); my @TGA; my $ntag; # 定数 $mark = pack("C", 0xff); %SHT = ( 'II' => 'v', 'MM' => 'n' ); %LNG = ( 'II' => 'V', 'MM' => 'N' ); # 初期値 $endian = ''; $width = -1; $height = -1; $format = ''; $Exif_IFD = -1; if( $in eq '' ){ $in = 'IMG'; } open( $in, $IMG ) || return( '', -1, -1 ); binmode($in); seek( $in, 0, 0 ); read( $in, $buf, 6 ); # GIF 形式 if($buf =~ /^GIF/i){ $format = 'GIF'; read( $in, $buf, 2 ); $width = unpack("v*", $buf); read( $in, $buf, 2); $height = unpack("v*", $buf); } close( $in ); return( $format, $width, $height ); } exit;

    • ベストアンサー
    • Perl
  • 10進数→2進数の出力について

    コマンドライン引数から10進数の値を入力して 2進数に変換して出力しようとしています。 ※入力される10進数の値はかなり大きなものを想定しています。 現在は下記のようなコードで変換しようとしていますが失敗しています。 動作環境は『WindowsXP、Activeperl-5.12.4.1205』です。 拙い説明ですが、よろしくお願いいたします。 # コマンドライン引数は「9223372036854775808」 $n = unpack("B8", pack("C", $ARGV[0])); print n; # 実行結果は「11111111」 # 期待している出力結果は「1000・・・000」(←0が64個) 9223372036854775808

    • ベストアンサー
    • Perl
  • バイナリデータの書込みについて

    こんにちは、初めまして。 さっそくなんですが、バイナリデータの操作を行っていて、ちょっと気になることがあり、質問させて頂きます。 現在あるバイナリデータファイルの読出しには成功し、一応思った通りに書込み、 そのデータは壊れず、読み出せたんですが・・・。 そのバイナリデータファイルは当然のように、アスキー型や文字型、ビッグエンディアンのshortやlongがバイト長ごとに入り混じってます。 アスキー型や文字型は問題なく読み書きできるんですが、 ビッグエンディアンのshortやlongを書き込む時、バイト長を指定してやると、データが壊れてしまいます。 例えば、2バイトのビッグエンディアンのshortを読み出して、そのままリスト値に変換をかけ、なにも加工することなく、再びバイナリ構造体に変換しても、データが壊れてしまいます。 例 失敗) INは読み出すファイル、OUTは書き込むファイル read (IN,$dataB,2); $dataA = unpack("n2",$dataB); $dataB2 = pack("n2",$dataA); print OUT $dataB2; 現在、packするときに、データ長をしてせず、*とすることでデータの書込みには成功してる(ちゃんと読めるデータとして)んですが、これから先、こういったデータを加工して書き込む場合、データ長を指定せずに書き込むというのは・・・。ちょっと嫌な感じです。 例 成功) INは読み出すファイル、OUTは書き込むファイル read (IN,$dataB,2); $dataA = unpack("n2",$dataB); $dataB2 = pack("n*",$dataA); print OUT $dataB2; 何が原因なのか、わからず困っています。 なにぶん素人なもので、やってること自体間違っているのかもしれませんが、どなたか御回答頂ければ幸いです。 ここに書いている質問の意図がわからない等、ありましたらその旨お答え頂ければ、私の知る限りお答えしようと思いますので、どうか宜しくお願い致します。

    • ベストアンサー
    • Perl
  • [Perl] Pack関数について教えてください。

    こんにちは。 下記は、pack関数のサンプルスクリプトですが、 なんでそのような結果になるのか、よくわかりません。どなたか教えていただけますか。 print "文字列を入力してください:"; $string = <STDIN>; chomp ($string); $length = length($string); print "数値を入力してください:"; $number = <STDIN>; chomp ($number); # Do Pack! $packed = pack("A${length}i", $string, $number); print "パック文字列: $packed\n"; --- 結果 --- 文字列を入力してください:perl 数値を入力してください:100 パック文字列: perl

    • ベストアンサー
    • Perl
  • bigintのpack

    Perlで16進数→10進数→二進数の変換を行うために packとunpackを使用するのですが 32ビット以上の数であるためにbigintを使用しています。 そのときに 10進→二進変換 二進→10進変換などはどのように行えば良いのでしょうか? 32bitまでならば sub bin_dec { return (unpack("N",(pack("B32", $_[0])))); } sub dec_bin { return (unpack("B32", pack("N", $_[0]))); } のように行えるのですが Nは32bitのlong型のままですので 4294967295以上の数は4294967295になってしまいます。 どうすれば良いのでしょうか? Bit/Vectorモジュールは使えないものとします。

    • ベストアンサー
    • Perl
  • perlがうごきません

    <html> <head> <title>form3</title> </head> <body> <form action="form3.cgi" method="post" name="form3"> <input type="text"name="form3"> <input type="submit"value="送信"> </form> </body> </html> ::::::::::::::::::::::::::::::: #! /usr/bin/perl if($ENV{"REQUEST_METHOD"} eq "GET"){ $str=$ENV{QUERY_STRING"}; }else{ read(STDIN, $str, $ENV{"CONTENT_LENGTH"}); } $str=~ tr/+/ /; $str=~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("c", hex($1))/eg; foreach(split(/&/, $str)){ my ($key, $value)=split(/=/, $_); $data{$key}=$value; } print "Content-type:text/html\n"; print "\n"; print "<html>\n"; print "<head><title>form3</title></head>\n"; print "<body>$data{'form3'}</body>\n"; print "</html>\n"; exit; :::::::::::::::::::::::::::::::: どうしてもうごきません。 どこかスクリプトがまちがっているのでしょうか。 パールのパスはあっています。

    • ベストアンサー
    • Perl
  • フォームで入力されたアドレスに内容のコピーを自動返信

    下記フォームのCGIに、フォームで入力したアドレスに内容のコピーを自動で返信したいと考えています。 htmlフォームのメールの項目は、name="mail"です。 $clength = $ENV{'CONTENT_LENGTH'}; if ($clength ne '') { read(STDIN, $query_string, $clength); @elements = split(/&/, $query_string); $i = 0; foreach $element (@elements) { ($key, $buf) = split(/=/, $element); $key =~ tr/+/ /; $key =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; &jcode'convert(*key, 'jis'); @name[$i] = $key; $buf =~ tr/+/ /; $buf =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; &jcode'convert(*buf, 'jis'); @value[$i] = $buf; $i++; } $mail = $FORM{'mail'}; &jcode'convert(*sname, 'jis'); &jcode'convert(*subject, 'jis'); &jcode'convert(*ftitle, 'jis'); open (MAIL, "| $sendmail -f $smail $trans"); if ($sname ne '') { print MAIL "From: \"$sname\" <$smail>\n"; } else { print MAIL "From: $smail\n"; } print MAIL "Content-Type: text/plain; charset=\"ISO-2022-JP\"\n"; print MAIL "Subject: $subject\n"; print MAIL "\n"; print MAIL "$ftitle\n"; print MAIL "\n"; $tmp = '送信内容'; &jcode'convert(*tmp, 'jis'); print MAIL "$tmp\n"; print MAIL "----------------------------------\n"; for($j = 0; $j < $i; $j++) { print MAIL $j+1 . ": @name[$j] => @value[$j]\n"; } print MAIL "------------------------------------\n"; close(MAIL); print "Location: $query_file\n\n"; }

    • 締切済み
    • CGI
  • ファイル読み込みを配列に入れる方法

    ファイルから数字を読み込んで 並び替えて出力するプログラムを作成しているのですが ファイルから一度に配列に取り込んで、その配列で並び変えたいのですが取り込みができないのです、int型の配列に一度に取り込むのは可能なのでしょうか? import java.io.*; class Sort { public static void main(String[] args) { String path = args[0]; File file = new File(path); FileReader fr = null; int[] buf = new int[(int)file.length()]; try { fr = new FileReader(file); fr.read(buf); for (int i=0; i<buf.length-1;i++) { int mini=buf[i]; int miniIndex = i; for(int j = i+1; j<buf.length;j++){ if(buf[j] < mini){ mini = buf[j]; miniIndex = j; } } buf[miniIndex] = buf[i]; buf[i] = mini; } for(int i =0; i<buf.length;i++) { System.out.print( buf[i]+","); } } catch (IOException e) { System.out.println("ファイル入力エラー"); } } } と作ってみたのですが‥ ご教授お願いいたします。

    • ベストアンサー
    • Java
  • perl初心者 「カウンタ」の2

    「とほほ」さんのgif画像連結ライブラリを使ってカウンタを作成中、行き詰ってしまいました。 下のスクリプトはあるサイトで配布されているカウンタのスクリプトの一部です。 1 while (length($count) < $fig) { $count = '0' . $count; } 2 $length = length($count); 3 @GIF=(); 4 foreach (0 .. $length-1) { 5 $n = substr($count,$_,1); 6 push(@GIF, "$imgdir/$n\.gif"); 7 } 8 9 print "Content-type: image/gif\n\n"; 10 binmode(STDOUT); 11 print &gifcat'gifcat(@GIF); * $figはカウンタ表示桁数です。 * $imgdirはカウンタ画像のディレクトリです。 このスクリプトを組み込んだらうまいことカウンタを表示することができました。 でもスクリプトの理解ができず悩んでいます。 お暇がありましたらぜひ教えてください。

  • フォームのINPUT NAMEが日本語化け

    CGIがまったく分からない者ですが、会社からホームページ管理を任されてしまいました。INPUT NAMEを日本語にすると文字化けになり、困っております。ご存知の方、どうか中のソースをどう編集したら良いのか細かく頂けたら本当に助かります。 以下、CGIのソースです。 #本文タイトル $honbun_title = '■□ 申込 ■□'; #time #($sec, $min, $hour, $mday, $mon, $year, $wdy, $yday, $isdst) = Localtime(time); $clength = $ENV{'CONTENT_LENGTH'}; if($clength ne '') { read(STDIN, $query_string, $clength); @elements = split(/&/,$query_string); $i = 0; foreach $element (@elements) { (@name[$i], $buf) = split(/=/, $element); $buf =~ tr/+/ /; $buf =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; &jcode'convert(*buf, 'jis'); @value[$i] = $buf; $i++; } &jcode'convert(*honbun_title, 'jis'); &jcode'convert(*ftitle, 'jis'); open (MAIL, "|$sendmail $trans"); print MAIL "From: $smail ($sname)\n"; print MAIL "Subject: $ftitle\n"; # print MAIL "$year\n\n" print MAIL "$honbun_title\n\n"; for($j = 0; $j < $i; $j++) { print MAIL "■@name[$j] : "; print MAIL ": @value[$j]\n\n"; } close(MAIL); print "Location: $query_file\n\n"; }

    • 締切済み
    • CGI