アプリ版:「スタンプのみでお礼する」機能のリリースについて

scanf( )ライブラリが仕様上の問題により
業務上のプログラムで使われない理由って
何ですか?

またその代わりに何を使えばいいんですか?

A 回答 (8件)

>scanf( )ライブラリが仕様上の問題により


仕様上の問題が何を指しているかわかりませんが。。。?

>業務上のプログラムで使われない理由って何ですか?
仕様がきちんと理解されない。
危ないと教えられたからそれを妄信している人が多い。
#事実危ないですが、キチンと使えばそれなりに安全です。
というレベルかと。

>またその代わりに何を使えばいいんですか?
「代わりに」とありますが、処理によっては代わりにならないかも。
文字列を標準入力から文字列を受け取るレベルなら、
殆どの処理系でfgetsが使われます。
    • good
    • 0

> またその代わりに何を使えばいいんですか?



scanfの代わりに何を使うかは目的によって異なりますし、それがscanfより優れているかというと、必ずしもそうではありません。
よく言われるfgets + sscanfにしても、#5で説明したように、整数、浮動小数点数、ワイド文字(列)に対してはエラーチェックができません。また、

char str[31+1];
scanf("%31[^\n]%*[^\n]%*c", str);

のようにして1行入力するコードをfgetsで置き換えるには、改行文字を除去したり、配列に格納し切れなかった読み残しの文字を捨てたりと、結構面倒な処理を行う必要があります。
    • good
    • 0

>業務上のプログラムで使われない理由って何ですか?



プログラム内にscanf("%d",&a);などの数値入力用のscanfしかなく、ループしている時に、「0,1」などと入力すると「,」を処理することができなくなり、「stdin」がプログラム終了まで使えなくなります。

1文字の打ち間違いで、残りの入力が使えなくなるような関数を業務用のプログラムで使えるわけがありません。

>またその代わりに何を使えばいいんですか?
他の方の言うように、fgets,sscanfを使ってください。
    • good
    • 1

>バッファオーバーランではなく、


>数値がオーバーフローやアンダーフロー
ご指摘ありがとうございます...orz

>scanf("%s")では、バッファオーバーランが起き得ます。
%sでは読み込むバイト数を指定すれば、
バッファオーバランを回避することができます。

>fgets+sscanf
sscanfの仕様もscanfの仕様も入力ストリームが違うだけで
スキャン集合の仕様には差異がありません。

今回の質問に関して言えば、開発者の中でもNo4さんのように
考えている方が非常に多いというのが理由だと思います。
#わたしもC言語の規格書を読むまではそう思っていましたし。。。
    • good
    • 0

scanf系の関数は、入力内容の誤りを検出することがほとんどできません。


よく言われるバッファオーバーランは実は回避可能で、本当の問題は数値のエラー判定ができないことにあります。
基本的には、#2さんのご指摘どおりなのですが、バッファオーバーランではなく、数値がオーバーフローやアンダーフローを起こして、格納先の型で表現できない場合の動作が未定義になります。

他には、%lsや%lcを用いた場合、不正な多バイト文字であったり、その時点でのロケールで適切なワイド文字への変換が行えない場合に破綻してしまう問題もあります。

こうした問題は、fgets + sscanfに置き換えても何の解決にもなりません。

参考URL:http://www.kijineko.co.jp/tech/superstitions/buf …
    • good
    • 0
この回答へのお礼

参考になりました

お礼日時:2007/12/25 17:49

scanf("%d")ではバッファオーバーランは起きないと思いますけどね。

(ソースコードに当たって確認したわけではありませんが、常識的なアルゴリズムであれば)

scanf("%s")では、バッファオーバーランが起き得ます。
注意して使えば済むだけなのですが、「scanfは一切使うな」といって済ませてる傾向が強いです。

scanfをfgets+sscanfに置き換えるとか、そもそもscanf系の関数を使わないとか、いろいろ。
    • good
    • 0

今の時代、業務上のプログラムがscanf()を使うような


コンソール・アプリケーションであるケースは、
ほとんどないと思います。
    • good
    • 0

>事実危ないですが


一応何が危ないかというと、

int num;
scanf("%d",&num );
こういうコードに対して、int型の表現範囲を超える数値が
(例えば9999999999999999999999999999999999999999999999999999など)
入力されるとバッファオーバランするからです。

>文字列を標準入力から文字列を受け取るレベルなら、
>殆どの処理系でfgetsが使われます。
日本語おかしいですね;
「文字列を標準入力から受け取るレベルなら、
 殆どの処理系でfgetsが使えます。」
が正しいです。
    • good
    • 1
この回答へのお礼

ありがとうございます

お礼日時:2007/12/20 19:35

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!