Perlが終了する前に最後のテキストを印刷しないのはなぜですか?

StackOverflow https://stackoverflow.com/questions/636083

  •  10-07-2019
  •  | 
  •  

質問

私のコードは"の直前の最後の行を実行しません exit; "理由はわかりません。 exit の前に printf $ fh 行を追加しようとしましたが、それでもうまくいきませんでした。どちらの行も印刷しません。終了前の最後の印刷ステートメントを除き、他のすべてが正常に印刷されます。

これがなぜ起こるのか、手がかりはありますか?それとも、それを修正または回避する方法ですか?

    if($i>0 && $i<3)
    {
        printf $fh "Partial match found.\n";
        if($matched_uid){printf $fh "UID #: ".$arguid." exists.\n";}
        if($matched_id){printf $fh "ID #: ".$argid." exists.\n";}
        if($matched_uname){printf $fh "Username: ".$arguname." exists.\n";}
        printf $fh "Aborting."; 
        exit;
    }

編集:
コピーしたコードの一部にはこれが含まれていました

select $fh; $| = 1; #set auto flush

これが私の結果を複製できなかった理由かもしれません...

役に立ちましたか?

解決

「中止」を試してください。\ n&quot;

これはバッファリングの問題のように見えます。

他のヒント

Rを渡しました。 Bemrose 私の投票ですが、$ fhが FILE HANDLE の場合、終了する前に close することもできます。

また、 printf を誤って使用しています。 printfは「印刷ファイル」ではありませんではありません。その「印刷形式」。

最後の例の場合

  print $fh 'Message' ;  

必要なのはこれだけです。

printf は次のように使用することを目的としています。

printf $fh 'some format %s  and more %s ' ,  $var , $var ; 

または

   printf 'some format %s  and more %s ' ,  $var , $var ; 

およびその実行と同等

   print $fh sprintf 'format %s more %s' , $var , $var ; 

このため、連結された変数のいずれかが展開されて '%'が含まれる場合、不必要なコードリスクが発生します。このtrapに陥る人々の例については、 Qをご覧ください。 :308417:Perlスクリプトがファイルから文字を削除するのはなぜですか?

perldoc -f print

print FILEHANDLE LIST
print LIST
print   Prints a string or a list of strings.

perldoc -f printf

printf FILEHANDLE FORMAT, LIST
printf FORMAT, LIST
      Equivalent to "print FILEHANDLE sprintf(FORMAT, LIST)", except that "$\" 
      (the output record separator) is not appended

さらなる調査

「バッファリング」を取得できないため、さらに問題を調査しています。発生する条件。すべてのファイルは、フラッシュするかどうかにかかわらず、適切にフラッシュされます。 (Perl 5.10)。

試しているコードスニペットは次のとおりです。

#!/usr/bin/perl 

use strict;
use warnings;


open my $fh , '>' , '/tmp/oo.txt'; 

my $exit_at = int(rand( 200_000 ));
print "$exit_at\n";
sleep 2;
for ( 0 .. ( $exit_at * 2 ) ){ 
    print $fh 

Rを渡しました。 Bemrose 私の投票ですが、$ fhが FILE HANDLE の場合、終了する前に close することもできます。

また、 printf を誤って使用しています。 printfは「印刷ファイル」ではありませんではありません。その「印刷形式」。

最後の例の場合

  print $fh 'Message' ;  

必要なのはこれだけです。

printf は次のように使用することを目的としています。

printf $fh 'some format %s  and more %s ' ,  $var , $var ; 

または

   printf 'some format %s  and more %s ' ,  $var , $var ; 

およびその実行と同等

   print $fh sprintf 'format %s more %s' , $var , $var ; 

このため、連結された変数のいずれかが展開されて '%'が含まれる場合、不必要なコードリスクが発生します。このtrapに陥る人々の例については、 Qをご覧ください。 :308417:Perlスクリプトがファイルから文字を削除するのはなぜですか?

perldoc -f print

print FILEHANDLE LIST
print LIST
print   Prints a string or a list of strings.

perldoc -f printf

printf FILEHANDLE FORMAT, LIST
printf FORMAT, LIST
      Equivalent to "print FILEHANDLE sprintf(FORMAT, LIST)", except that "$\" 
      (the output record separator) is not appended

さらなる調査

「バッファリング」を取得できないため、さらに問題を調査しています。発生する条件。すべてのファイルは、フラッシュするかどうかにかかわらず、適切にフラッシュされます。 (Perl 5.10)。

試しているコードスニペットは次のとおりです。

Modification of a read-only value attempted at iotest.pl line 15.

私は、printfの誤った使用を使用しています。 コメントされた行はエラーメッセージを排出します。これは、 'n'パラメータを提供しているユーザーがいないために無効であり、次のように終了するためです。

<*>

「最終行」印刷を実行する前(これも悪いですが、%記号がないので問題ありません)、「最終行」を出力ファイルから削除します。

printfを修正し、代わりにplain-old-printを使用して、問題が解決するかどうかを確認してください。

; if (

Rを渡しました。 Bemrose 私の投票ですが、$ fhが FILE HANDLE の場合、終了する前に close することもできます。

また、 printf を誤って使用しています。 printfは「印刷ファイル」ではありませんではありません。その「印刷形式」。

最後の例の場合

  print $fh 'Message' ;  

必要なのはこれだけです。

printf は次のように使用することを目的としています。

printf $fh 'some format %s  and more %s ' ,  $var , $var ; 

または

   printf 'some format %s  and more %s ' ,  $var , $var ; 

およびその実行と同等

   print $fh sprintf 'format %s more %s' , $var , $var ; 

このため、連結された変数のいずれかが展開されて '%'が含まれる場合、不必要なコードリスクが発生します。このtrapに陥る人々の例については、 Qをご覧ください。 :308417:Perlスクリプトがファイルから文字を削除するのはなぜですか?

perldoc -f print

print FILEHANDLE LIST
print LIST
print   Prints a string or a list of strings.

perldoc -f printf

printf FILEHANDLE FORMAT, LIST
printf FORMAT, LIST
      Equivalent to "print FILEHANDLE sprintf(FORMAT, LIST)", except that "$\" 
      (the output record separator) is not appended

さらなる調査

「バッファリング」を取得できないため、さらに問題を調査しています。発生する条件。すべてのファイルは、フラッシュするかどうかにかかわらず、適切にフラッシュされます。 (Perl 5.10)。

試しているコードスニペットは次のとおりです。

<*>

私は、printfの誤った使用を使用しています。 コメントされた行はエラーメッセージを排出します。これは、 'n'パラメータを提供しているユーザーがいないために無効であり、次のように終了するためです。

<*>

「最終行」印刷を実行する前(これも悪いですが、%記号がないので問題ありません)、「最終行」を出力ファイルから削除します。

printfを修正し、代わりにplain-old-printを使用して、問題が解決するかどうかを確認してください。

== $exit_at ){ printf $fh '%n' ; # Bad Code Causes Early Death. printf $fh 'last line'; exit; } if (

Rを渡しました。 Bemrose 私の投票ですが、$ fhが FILE HANDLE の場合、終了する前に close することもできます。

また、 printf を誤って使用しています。 printfは「印刷ファイル」ではありませんではありません。その「印刷形式」。

最後の例の場合

  print $fh 'Message' ;  

必要なのはこれだけです。

printf は次のように使用することを目的としています。

printf $fh 'some format %s  and more %s ' ,  $var , $var ; 

または

   printf 'some format %s  and more %s ' ,  $var , $var ; 

およびその実行と同等

   print $fh sprintf 'format %s more %s' , $var , $var ; 

このため、連結された変数のいずれかが展開されて '%'が含まれる場合、不必要なコードリスクが発生します。このtrapに陥る人々の例については、 Qをご覧ください。 :308417:Perlスクリプトがファイルから文字を削除するのはなぜですか?

perldoc -f print

print FILEHANDLE LIST
print LIST
print   Prints a string or a list of strings.

perldoc -f printf

printf FILEHANDLE FORMAT, LIST
printf FORMAT, LIST
      Equivalent to "print FILEHANDLE sprintf(FORMAT, LIST)", except that "$\" 
      (the output record separator) is not appended

さらなる調査

「バッファリング」を取得できないため、さらに問題を調査しています。発生する条件。すべてのファイルは、フラッシュするかどうかにかかわらず、適切にフラッシュされます。 (Perl 5.10)。

試しているコードスニペットは次のとおりです。

<*>

私は、printfの誤った使用を使用しています。 コメントされた行はエラーメッセージを排出します。これは、 'n'パラメータを提供しているユーザーがいないために無効であり、次のように終了するためです。

<*>

「最終行」印刷を実行する前(これも悪いですが、%記号がないので問題ありません)、「最終行」を出力ファイルから削除します。

printfを修正し、代わりにplain-old-printを使用して、問題が解決するかどうかを確認してください。

% 1000 ){ print $fh "\n"; } }

私は、printfの誤った使用を使用しています。 コメントされた行はエラーメッセージを排出します。これは、 'n'パラメータを提供しているユーザーがいないために無効であり、次のように終了するためです。

<*>

「最終行」印刷を実行する前(これも悪いですが、%記号がないので問題ありません)、「最終行」を出力ファイルから削除します。

printfを修正し、代わりにplain-old-printを使用して、問題が解決するかどうかを確認してください。

Perlは出力をバッファリングします。で自動バッファリングをオフにできます

local $| = 1;

編集:なんとなくヒット!の代わりに|初めて...修正されました。それがどうして起こったのかわからない、彼らはキーボードの反対側にいる。

print を適切に使用することをテーマに、あなたは自分で物事を少し難しくします。

文字列を連結するのではなく、変数を補間します。 複数の文字列の代わりに、印刷する文字列のリストを含む1つのprintステートメントを使用します。

1つの方法を次に示します。

if( $i>0 && $i<3 )
{
    print $fh join "\n", 
        "Partial match found.",
        $matched_uid   ? "UID #: $arguid exists."      : (),
        $matched_id    ? "ID #: $argid exists."        : (),
        $matched_uname ? "Username: $arguname exists." : (),
        "Aborting.",
        ;

    exit;
}

三項演算子の偽側の()は空のリストで、結合する引数がフラット化されると消えます。空の文字列( '' )を使用していた場合、一致しない各基準は結果に余分な空白行を生成していました。

各項目に独自の改行を追加し、読みやすいと思う場合は結合をスキップすることもできます:

    print $fh  
        "Partial match found.\n",
        $matched_uid   ? "UID #: $arguid exists.\n" : '',
        ...

最後のprintfに末尾の\ nを追加する必要があります。そうしないと、出力はコンソールにフラッシュされません。

デビッド・ノーマンが正しいか、問題はどこか別の場所にあります。 ifブロック内のコードをperlインタープリターに入力したところ、「Aborting」と印刷されました。予想通り。 (改行文字がなくても機能しました。)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top