2016-07-27 11 views
3

を考えると、次の行:文字列の形式%80 [^、]はCの意味ですか?

char szInline[80]; 
char szDescription[80] = { NULL }; 
float fCost = 0; 
sscanf (szInline, "%80[^,], %f", szDescription, &fCost); 

% 80 [^は、]何をしますか?

+1

btw '{NULL}'は '{0}'または '{'\ 0'}'でなければなりません。 'NULL'は値0を持つポインタです。それを文字に代入すると、"整数変換への互換性のないポインタ "*警告が与えられます。 – user3386109

+0

@ user3386109:残念ながら、警告は表示されません。 'NULL'は、実装定義のヌルポインタ定数に展開され、通常は' 0'です。(もちろん、NULLポインタ定数*が必ずしもポインタ型の式であるとは限りません) –

+1

@ user3386109: 'NULL(NULL)'を '(void *)0'として定義しても、 C標準ライブラリの実装では非常に一般的な方法ですが、 'NULL'はポインタであることが保証されていません。このコードを有効にする整数値「0」にすることができます。しかし、あなたのポイントはまだ立っています。 「NULL」はそこにビジネスがありません。 'NULL'はポインタコンテキストにのみ予約されるべきです。 – AnT

答えて

4

最大80文字を次の,のカンマまで読みます。

ところで、szDescriptionバッファここで1

+1

「小さすぎる1」のバグをうまくキャッチ! – dasblinkenlight

+1

@dasblinkenlight:良いバグ候補ですが、入力文字列の最大長が79なのでこの特定のケースでは何の結果もありません。 – chqrlie

+0

@AnT:定義: 'char szInline [80];' 'szInline'が適切な文字列でない場合(ヌルバイトを含まない)場合、コードは未定義のビヘイビアを呼び出します。フラグメントは 'szInline'の初期化を省略していると仮定していますが、省略記号' ... 'はより明白になります。 – chqrlie

1

によって小さすぎるはsscanf(szInline, "%80[^,], %f", szDescription, &fCost)ためのステップである:

  • sscanf
  • 、アレイszDescription,異なる180文字間解析します成功した場合は、,文字に一致すると見なされます。
  • 見つかった場合は、空白文字('\n'を含む)を無視します。
  • 最後に浮動小数点数表現をfCostタイプのfloatに変換しようとすると、
  • 成功したコンバージョンの数を返します。または、EOFは早期の失敗のケースです。

そこに潜在的な問題があります。

  • は、先の配列szDescriptionは80文字プラス'\0'ターミネータ用短すぎるが、それならば幸いにも、入力配列szInlineも80の長さを有し適切な文字列が含まれています。最大で79文字はsscanfと一致するため、オーバーフローは発生しません。この特定の場合、サイズ指定子は実際には必要ありません。
  • ,の後のスペースは冗長です。 %fは常に先頭の空白を無視します。

sscanf()は、この入力にEOFを返すことに注意してください:入力文字列の先頭から解析する,異なる文字が含まれていないとして,1。この特殊なケースは、高度なCプログラマでさえ見過ごされがちです。

あなたが,前に、おそらく空の文字列を受け入れるようにしたい場合は、あなたが直接sscanf()を使用することはできませんが、これを使用することができます:

/* compute the length of the initial sequence upto `,` if any */ 
size_t len = strcspn(szInline, ","); 
/* len < 80 because sizeof(szInline) == 80 */ 
/* copying the initial string */ 
memcpy(szDescription, szInline, len); 
szDescription[len] = '\0'; 
if (sscanf(szInline + len, ",%f", &fCost) != 1) { 
    /* conversion error: no `,` or no number past it */ 
    ... 
} 

sscanf()は、多くの癖を持っている、何のために適切に使用することが難しいことで知らあります最も単純な解析作業です。めったに使用されない標準機能strspn()strcspn()は有用な代替手段です。

+0

scanfをオプションで80文字までマッチさせることができますか?1も成功するでしょうか? –

+0

'sscanf()'では直接ではありません。私の更新された答えを見てください。 – chqrlie

関連する問題