bc電卓で変数の初期化をカスタマイズする方法はありますか?

bc電卓で変数の初期化をカスタマイズする方法はありますか?

bc電卓が初期化されていない変数にゼロ値を割り当てるようです。 bcが初期化されていない変数を見つけた場合、式が無効とマークされるようにこの動作を変更したいと思います。たとえば、以下のコードでは

echo "foo + bar" | bc -l

bc は foo と bar に値 0 を割り当て、「0」を返します。空の文字列""を返すか、"foo + bar"が誤った式であることを示したい。 BCでこれを達成する方法はありますか?

ベストアンサー1

私の質問に答えるために、bcで宣言されていない変数を無効とマークすることに加えて、他の人に役立つ場合に備えて動作する解決策を思い出しました。 bc 実行される式はまず sed コマンドを介してパイプされます。このコマンドは、式から保持されているbcワードを削除します。残りの変数名は宣言されていない変数とみなされ、式全体がbcで実行されたときにエラーを強制する文に変換されます。 (私は「1/0」を選択しましたが、エラーフラグのどれでも多くの選択肢を設定できます。)

ランタイム「0で割る」エラーを生成します。

echo 'foo + bar' | sed -E '
    ## Save the original expression in the hold space
    h
    ## Recursively replace all bc reserved words with a unique token string (¦§§¦)
    :again
    s/auto|break|continue|define|else|for|halt|ibase|if|last|length|limits|obase|print|quit|read|return|scale|sqrt|warranty|while/¦§§¦/g
    s/(a|c|e|j|l|s)([(][^)]*[)])/¦§§¦\2/g
    t again
    ## If the expression contains any bc reserved words abutting one another, mark the expression as invalid, and skip to the end of the sed script
    /¦§§¦¦§§¦/s/^.+$/1\/0/
    t
    ## Replace all tokens with spaces
    s/¦§§¦/ /g
    ## If any variable names remain, treat them as undeclared variables, mark the expression as invalid, and skip to the end of the sed script
    ## Prior to doing this, reset the t command so that it can recognize if a substitution takes place in the s command
    t reset
    :reset
    /[a-z][a-z0-9_]*/s/^.+$/1\/0/
    t
    ## If the expression does not have undeclared variable names, get the original expression from the hold space
    g
' | bc -l

正解を返す = 246:

echo '123 + 123' | sed -E '
    ## Save the original expression in the hold space
    h
    ## Recursively replace all bc reserved words with a unique token string (¦§§¦)
    :again
    s/auto|break|continue|define|else|for|halt|ibase|if|last|length|limits|obase|print|quit|read|return|scale|sqrt|warranty|while/¦§§¦/g
    s/(a|c|e|j|l|s)([(][^)]*[)])/¦§§¦\2/g
    t again
    ## If the expression contains any bc reserved words abutting one another, mark the expression as invalid, and skip to the end of the sed script
    /¦§§¦¦§§¦/s/^.+$/1\/0/
    t
    ## Replace all tokens with spaces
    s/¦§§¦/ /g
    ## If any variable names remain, treat them as undeclared variables, mark the expression as invalid, and skip to the end of the sed script
    ## Prior to doing this, reset the t command so that it can recognize if a substitution takes place in the s command
    t reset
    :reset
    /[a-z][a-z0-9_]*/s/^.+$/1\/0/
    t
    ## If the expression does not have undeclared variable names, get the original expression from the hold space
    g
' | bc -l

編集者注:これは元々提出されたものを改善し、宣言されていない変数名を検索するためにより正確になりました。

おすすめ記事