scanfはなぜ糞仕様なのか

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
?
2デフォルトの名無しさん:2010/08/17(火) 11:06:31
糞スレ
3デフォルトの名無しさん:2010/08/17(火) 11:17:16
最近Cプログラミングを始めたの?
ガ・ン・バ・レ!
4デフォルトの名無しさん:2010/08/17(火) 13:33:28
今日も暑いな
5デフォルトの名無しさん:2010/08/17(火) 13:35:47
入門用だからシンプルすぎるんだろ
6デフォルトの名無しさん:2010/08/17(火) 15:09:52
           皆様へのお願い

  このスレッドは高次機能障害をもたらす
病理の臨床実験のために立てたものです。

  被験者と研究員のやり取りに使うため、
書き込み等は自重されるようお願いいたします。
もし、書き込み等をすることで不愉快な思いをされましても、
当研究所は責を負いかねます。



                      (社)京都微生物研究所
7デフォルトの名無しさん:2010/08/17(火) 16:30:38
アイちゃんは昔からよく見たけど、最近は>6が主流なのか?
8デフォルトの名無しさん:2010/08/17(火) 20:22:22
>>5
ぜんぜんシンプルじゃない。
9デフォルトの名無しさん:2010/08/17(火) 21:14:33
バカはC#(笑)使ってるのがお似合いだと思います
10デフォルトの名無しさん:2010/08/17(火) 21:25:22
>>9
それはscanf()は最高級に難しいテクノロジーでそれをバカにするのは
それを使いこなせないC#ユーザーに違いないという推測に基づく発言か。

残念ながら、scanf()がクソだというのはプログラマの99%の共通認識だ。
そう認識してないのは専門学校のscanf()を使いまくったうんこみたいな
テキストで勉強してそのレベルにとどまってるウンコPGだけだ。
11デフォルトの名無しさん:2010/08/17(火) 21:54:04
scanfは、Cライブラリ最大の糞仕様といっていい。
12デフォルトの名無しさん:2010/08/18(水) 00:29:34
このスレッドは天才チンパンジー「アイちゃん」が
言語訓練のために立てたものです。

アイと研究員とのやり取りに利用するスレッドなので、
関係者以外は書きこまないで下さい。

                  京都大学霊長類研究所
13デフォルトの名無しさん:2010/08/19(木) 23:30:43
まあなんだかんだいっても大会とかで使うんですけどね
14デフォルトの名無しさん:2010/08/21(土) 01:20:54
scanfという文字列を20年ぶりに見た
15デフォルトの名無しさん:2010/08/21(土) 21:13:21
sscanf()なら使うけどねぇ。
scanf()系は入力を破棄し難いこととprintf()系の"%*d"みたいな
動的な幅指定がないのは厄介だけど、
文字列を対象とするsscanf()ならそれなりに使える。
16デフォルトの名無しさん:2010/08/22(日) 11:29:35
糞仕様だよ使えねーで済ませれば問題無いのに
初心者用入門書で最初の方で出てくるからなぁ
17デフォルトの名無しさん:2010/08/22(日) 11:56:02
初心者だからこそあえて洗礼を浴びせるのだ
18デフォルトの名無しさん:2010/08/22(日) 12:07:53
どのみちCはプログラマ自身がメモリ管理に精通しないと使いこなせないからな
一から十まで初心者に扱いやすいライブラリなんか用意しておく道義すらない
19デフォルトの名無しさん:2010/08/22(日) 14:46:36
初心者本でscanf()を使う奴は実務経験ないんじゃないかと思う。
まぁ、実務経験があってまともに文章を書けるのなら初心者本以外の仕事があるんだろうけれど。
ついでに言えば、printf()系でも"%f"を闇雲に使うよりは"%g"を使わせた方が余程初心者に向いていると思う。
酷い本になると、printf()系とscanf()系の書式指定子は互換性があるみたいな大嘘を書いてあるからね。
20デフォルトの名無しさん:2010/08/22(日) 19:18:58
printf("%lf", d);
は良く見かける
21デフォルトの名無しさん:2010/08/22(日) 20:28:18
>>20
それも問題だね。
22デフォルトの名無しさん:2010/09/03(金) 17:49:43
scanf_s
23デフォルトの名無しさん:2010/12/16(木) 01:40:45
fortranと違って、組み込みではないから
しかたがない。
24デフォルトの名無しさん:2010/12/16(木) 05:50:16
正規表現か何かのパターンマッチは標準で欲しいな
ライブラリ探してくるのめんどい
25デフォルトの名無しさん:2010/12/16(木) 07:31:45
>>24
スキャンセットだけでは不足ですか?
尤も、入門書でスキャンセットの存在にまで言及しているものは少ないし、
実例を挙げているものは皆無に等しいから面倒であることには同意。
26天使 ◆uL5esZLBSE :2011/07/01(金) 16:56:02.29
> 初心者用入門書で最初の方で出てくるからなぁ
ゴミみたいな奴だな
今日何ゴミの日だっけ?
27デフォルトの名無しさん:2011/07/01(金) 22:46:08.53
不燃物
びん、缶 (飲料缶除く)、天使を騙る痛いニート等
28天使 ◆uL5esZLBSE :2011/07/02(土) 12:11:29.33
>>27
------------------
[[[[[[[[[[[[ びん、缶 (飲料缶除く)、天使を騙る痛いニート等 ]]]]]]]]]]]](きリッッッッ!!ッ!!!
--------(キリ!!キリッッ!きリッ!!!キリッ!!!

気持ち悪い
29デフォルトの名無しさん:2011/10/16(日) 15:15:53.77
[迷信] scanf ではバッファオーバーランを防げない
http://www.kijineko.co.jp/tech/superstitions/buffer-overrun-of-scanf.html
30デフォルトの名無しさん:2011/10/16(日) 16:05:18.29
>>29
scanf("%10s", s); とかフォーマット文字列にバッファサイズ直書きしなければ
ならないのがすごいイヤな感じ。
バッファに残ったデータを読み飛ばす方法とかテクニックに走りすぎで美しくないし。
読み込みの単位が文字単位でも行単位でもないのが気持ち悪い。
あと%dとかで数値を読むときにオーバーフローを検出できないのもあとあと
面倒になる。
31デフォルトの名無しさん:2011/10/16(日) 22:24:47.60
>>30
そこはリンク先も言及してるね、まぁその時点でクソ仕様なわけだがw
別にリンク先がscanfは素晴らしいとか言ってるわけではないからどうでもいいか
32デフォルトの名無しさん:2011/10/16(日) 22:38:29.78
文字列から数値にするならエラーチェック出来るstrtol()使えってことだな
33デフォルトの名無しさん:2011/10/17(月) 00:08:15.74
>>30
>scanf("%10s", s); とかフォーマット文字列にバッファサイズ直書きしなければ
>ならないのがすごいイヤな感じ。

scanf 系関数での文字列長指定方法
http://www.kijineko.co.jp/node/201
34デフォルトの名無しさん:2011/10/17(月) 00:51:47.79
あそこまで来たら素直にfgets使えよってなるしなw
35デフォルトの名無しさん:2011/10/17(月) 01:33:22.52
昔、処理が遅すぎる時代に自動化させるために使ったという話をどこかで聞いたような
36デフォルトの名無しさん:2011/10/17(月) 12:43:43.12
でにすりっちーさんのごめいふくをおいのりします

          _____
  .ni 7    /        \  ご冥福をお祈りします
l^l | | l ,/) / /・\  /・\ \    .n
', U ! レ' / |    ̄ ̄    ̄ ̄  |  l^l.| | /)
/    〈  |    (_人_)    |  | U レ'//)
     ヽっ     \   |    /   ノ    /
 /´ ̄ ̄ ノ     \_|    \rニ    |
                      `ヽ   l
37デフォルトの名無しさん:2011/10/17(月) 20:19:22.46
>>33
うわぁ。やめてほしい。
38デフォルトの名無しさん:2011/10/28(金) 22:45:03.40
sscanf()はわりと使ってるかも。
39デフォルトの名無しさん:2011/10/29(土) 10:06:22.38
>>37
お前が理解できないことやってるからか?ww
40デフォルトの名無しさん:2011/12/18(日) 03:05:43.69
>>15
scanf( "%*s" );
入力破棄なんて、これだけの事でしょ。

if( 1 != scanf( "%d", &value ) )
      scanf( "%*s" );
入力失敗だってこれだけで廃棄できる。

>>24
パターンマッチ自体は、scanfでできるじゃん。
if( 1 == scanf( " < %s", tag ) )
{
      do
          count = scanf( " %[ \t\n] = \"%[^\"] %[/>]%[>]",  &key, &value, &terminate, &terminate );
      while( 2 != count );
}

例えば、こう書けば、下みたいなタグしか拾ってこなくなる。
<tag key = value"/>
<tag key = value">
<tag
   key = "value"
>
41デフォルトの名無しさん:2011/12/18(日) 03:06:21.91
馬鹿には無理
42デフォルトの名無しさん:2011/12/18(日) 03:10:45.90
>>30
#define Q(n) #n
#define LEN 10

char array[s];
scanf("%" Q( LEN ) "s", &s);
これで直書き自体は防げるぞ。
4340:2011/12/18(日) 03:12:31.43
まちげぇた。

× while( 2 != count );
○ while( 2 == count );
4440:2011/12/18(日) 03:20:34.57
肝心なとこも間違えてたわ。すまんすまん。

× " %[ \t\n] = \"%[^\"] %[/>]%[>]"
○ " %s = \"%[^\"] %[/>]%[>]"
45デフォルトの名無しさん:2011/12/18(日) 04:19:17.64
>>30
32bitで10億未満なら、フィールド幅を9桁にして、
その後判定すりゃいい。
10億越えるなら、32bit以上の型で読み取れ。
46デフォルトの名無しさん:2011/12/18(日) 05:11:12.02

char array[s];

char array[s];

char array[s];

char array[s];

char array[s];
47デフォルトの名無しさん:2011/12/20(火) 01:38:24.26
scanf便利じゃん。
48デフォルトの名無しさん:2011/12/24(土) 23:20:07.07
いや、つかえねーわ。
49デフォルトの名無しさん:2011/12/25(日) 22:04:42.24
お前がな
50デフォルトの名無しさん:2011/12/25(日) 23:57:50.86
UNIXを使ったことのないガキが言ったんだろ?
51デフォルトの名無しさん:2011/12/26(月) 07:34:36.57
ふーん
52デフォルトの名無しさん:2011/12/26(月) 22:07:18.38
scanf()とfscanf()を使ってるやつは信用できない。
sscanf()は、まあ許す。
53デフォルトの名無しさん:2011/12/26(月) 22:17:02.21
意味が解からん。sscanfはバッファー移動させる分非効率じゃん。
sscanfは自動でバッファーのシークまでしてくれないぞ。
54デフォルトの名無しさん:2011/12/27(火) 01:56:08.85
しないから良いんだよ馬鹿
55デフォルトの名無しさん:2011/12/27(火) 15:06:08.92
scanfに限らないけど、対話が必要ならどうしてもGUIの方に分があるよね
56デフォルトの名無しさん:2011/12/27(火) 18:55:20.73
replはCUIじゃないと
57デフォルトの名無しさん:2011/12/27(火) 20:38:15.06
>>54
ストリームデータに対しシークしないことになんのメリットがあんだよ
58デフォルトの名無しさん:2011/12/28(水) 16:27:29.52
scanfにケチつけてるヤツの何がイラッとするかって、
scanfで設定ファイルの解析すらしたこと無いくせに
ドヤ顔をで糞だと言っているところ。
使ったこともないプログラミング言語を貶してる連中と
同じウザさがある。
59デフォルトの名無しさん:2011/12/28(水) 17:02:55.78
そういう時は、普通はfscanf()を使うかfgets()とsscanf()を使うからなぁ。
60デフォルトの名無しさん:2011/12/28(水) 17:12:15.40
scanfもfscanfも大差ないがな
ただシェルをメインで使うなら
$xxxx-restore < xxxx.config
ってな感じで読み込む事はある。
あと設定じゃなきゃパイプ処理で重宝する
mplayer $( ls -l | a.out -m "50" )
とか、フォーマットの決まったデータをフィルタするのにね
61デフォルトの名無しさん:2011/12/28(水) 17:30:48.18
嘘を嘘と見抜けないひとは scanf を使うのは向かない
62デフォルトの名無しさん:2011/12/28(水) 20:35:24.64
>>53
バッファに移動するのが非効率とか、そんなパフォーマンス気にするならscanf()とか使うなよ。
63デフォルトの名無しさん:2011/12/28(水) 22:35:40.70
速度の効率じゃなく記述の効率だろ
64デフォルトの名無しさん:2011/12/28(水) 22:58:21.31
sscanfで簡潔に書けるというなら、
sscanfでこれと同じ動作するコード書いてみろよ。

int count;
do
{
     char key[1024], value[1024], invalid_string[4096];
     count = scanf( " %1023[^\t\n =] = \"%[^\"]\" ;", key, value );
     switch( count )
     {
          case 2:
                map[key] = value;
          break
          case 1:
               throw ParseValueInvalid( key );
          case 0:
               scanf( "%4095[^;];", invalid_string );
               throw ParseError( invalid_string );
     }
}while( EOF != count );
65デフォルトの名無しさん:2011/12/28(水) 23:44:07.70
>>64
valueに改行を含めるって仕様にしなかったらsscanf()でも一行増えるだけなんじゃね?
66デフォルトの名無しさん:2011/12/28(水) 23:49:39.86
エラーリカバリが面倒だからエラーが起きたら例外なげてるんだろうけど、
シンプルに一行一データって仕様にしたら、エラーのあった行だけ棄てて
次に読み進めるって処理も簡単に書けるな。
つまりシンプルにfgets()を使うのが、処理に柔軟性を持たせてまぎれのない
コードになるっていつもどおりの結論だ。
67デフォルトの名無しさん:2011/12/29(木) 00:06:10.89
scanf( "%*[^;];" );
破棄するほうが簡単なんだけど。
68デフォルトの名無しさん:2011/12/29(木) 00:08:08.50
>>65
ポインタのシークとバッファをまたがる値に対する処理が入る。
4行以上は増えるだろ。
69デフォルトの名無しさん:2011/12/29(木) 00:09:27.29
>>66
自分でいったとおりコード書いてみろよ。
そのやり方でもscanfで書いたほうが短いから。
70デフォルトの名無しさん:2011/12/29(木) 00:21:36.09
scanfの仕様を把握してないバカの言い訳が見苦しいなw
71デフォルトの名無しさん:2011/12/29(木) 01:29:58.34
だからscanfは糞だって言われてるんだよ
72デフォルトの名無しさん:2011/12/29(木) 01:43:15.03
scanf一つでプログラマの習熟度が解るな
73デフォルトの名無しさん:2011/12/29(木) 15:14:43.81
649 デフォルトの名無しさん [sage] 2011/12/29(木) 14:50:37.28 ID: Be:
学生プログラマ日本一決定戦(予選は社会人も参加可)
ttp://codevs.jp/howto.html
現在予選開催中
応募締切 2012.1.6 12:00

おもしろいことやっているじゃん。誰か今から参加しろよ。
74デフォルトの名無しさん:2011/12/29(木) 16:50:15.49
>>66
記述量が多くなるわけだが。
75デフォルトの名無しさん:2011/12/29(木) 19:40:30.75
>>66
ループ中で>>64を関数として呼び出し、読み込みを継続する事もできるんだけど。
ループ中で例外受け取って、
例外内容は例外リストに追加。
次の読み込み処理を実行。
76デフォルトの名無しさん:2011/12/30(金) 11:04:00.23
>>66
1行1データに囚われてる時点で柔軟性に欠けてるだろ
Jsonに書き直そうとしただけで大幅に手間が掛かる
77デフォルトの名無しさん:2011/12/30(金) 15:43:14.82
>>67
それ、エラーのあった行に ; が無かったら次の正常な行まで読み飛ばすじゃん。
iniファイルもどきの初期設定ファイルなんだから、変に仕様を複雑化しないでやっぱ一データ一行のほうがシンプルでいいな。
78デフォルトの名無しさん:2011/12/30(金) 15:44:01.78
>>76
scanf()でもjsonのパースとかできなさそうだけど。
79デフォルトの名無しさん:2011/12/30(金) 16:03:10.91
80デフォルトの名無しさん:2011/12/30(金) 17:00:27.41
>>78
すでにスレに上がってるコードみても分からないの?
コード書いてもらわないとダメなの?
81デフォルトの名無しさん:2011/12/30(金) 17:02:23.84
>>77
何か問題でも?
CやXMLのパーサーでも同じだろ
iniしかパースした事ないの?
82デフォルトの名無しさん:2011/12/30(金) 17:20:13.84
>>77
改行が消えて次の行と繋がったら、
次のデータ読み飛ばされるじゃねぇか
変わらねぇよ。
83デフォルトの名無しさん:2012/01/16(月) 04:11:45.24
C++ で、scanf 使うやついるのか。
84デフォルトの名無しさん:2012/01/21(土) 16:47:37.96
scanfはともかくfscanfの需要は多いだろ。
std::cinじゃパターンマッチが糞だから。
85デフォルトの名無しさん:2012/08/17(金) 16:11:44.59
istreamに使えるboost.formatみたいなのがあればなあ
86デフォルトの名無しさん:2012/10/08(月) 22:55:13.09
87デフォルトの名無しさん:2012/10/09(火) 17:20:09.82
scanfにアンパサンドが付く理由が未だによく分からない。
88デフォルトの名無しさん:2012/10/09(火) 17:22:34.97
>>87
付けずに実行してみ

出来れば int とかで初期値を 0 にしてみて
89デフォルトの名無しさん:2012/10/09(火) 23:39:02.39
私はウンコをしながらscanfを使います。
90デフォルトの名無しさん:2012/10/10(水) 04:51:17.64
       //
     /  /   バカッ
     //⌒)∩__∩
    /.| .| ノ     ヽ
    / | |  ●   ● |     
   /  | 彡  ( _●_) ミ 馬鹿には無理
   /  | ヽ  |∪|  /_
  // │   ヽノ  \/
  " ̄ ̄ ̄ ̄ ̄ ̄ ̄(..ノ
91デフォルトの名無しさん:2012/10/10(水) 10:17:52.71
stdio.hをみても、わからんなぁ
可変個だから
...とかいてある
92デフォルトの名無しさん:2012/10/10(水) 10:25:37.03
#include <stdio.h>

int subscanf(int *p)
{
  return scanf("%d", p);
}

int main(void)
{
  int i;

  printf("Enter a number: ");
  subscanf(&i);
  printf("%d\n", i);
  return 0;
}
93デフォルトの名無しさん :2012/10/11(木) 13:51:28.10
scanfがクソなのは、入力ストリームに'\n'残すからだろ
C++のstd::cinは毎回入力ストリームがかわるから残らない。
94デフォルトの名無しさん:2012/10/11(木) 14:35:50.72
fgets() とか fread とかも本来 EOF のところで NULL 返したり変な仕様だよ
NULL チェックより feof() でチェックした方が良いと思って併用するとおかしなことになるし
95デフォルトの名無しさん:2012/10/11(木) 14:43:51.05
>>94
fgets()はともかく、fread()はNULLは返さないぞ。
96デフォルトの名無しさん:2012/10/11(木) 14:47:58.77
>>93
残すよ。
int foo;
std::cin >> foo;
char bar;
std::cin.get(bar);
std::cout << '>' << bar << ">\n";
そもそも、「入力ストリームがかわる」ってのが何を言いたいのかわからん。
97デフォルトの名無しさん
>>95
読み込めた要素数を返す

EOF のときは要素数 0

0 はたまたま NULL と同じ値