2016-04-08 9 views
1

特定の単純なフォーマットの文字配列をチェックし、同時にその中の2つの数値の値を取得する必要があります。メッセージのフォーマットは、START番号番号ENDです。フォーマットを確認し、sscanfで番号を取得するC++

int x,y; 
if (sscanf(buffer, "START %d %d END", &x, &y) != 2) 
    return false; 
... 
... 
... 
return true; 

しかし、これは当然の数字が得られたので、結末が全く異なることにも成功した後:私が思い付くことができるすべては、このでした。それを行う最善の方法は何ですか?提案ありがとう。

+0

バッファの内容と文字列 "START%d%d END"が混在しているようです。 sscanfはあなたの文字列と2番目の文字列、つまり 'sscanf(" START 9 10 END "、"%s%d%d%s "、buff1、&x、&y、buff2)のフォーマットデータを含むバッファを待ちます。あなたは何をしようとしているのですか ? – auburg

+0

sscanfをフォーマット文字列 "START%d%d"で呼び出し、すべてがOKの場合は、フォーマット文字列 "%s"でsscanfを呼び出し、結果を "END"と比較してください。 – pointer

+0

@auburgの場合、フォーマットデータ**は** "START%d%d END"です。つまり、文字列には通常の文字が含まれている必要があります。 scanf形式で%sを使用することは危険であり、常に避けるべきです。%5sと%3sを使用した場合、あなたの提案はOKです。 –

答えて

1

C標準を確認した後、私はこれを検出する移植可能な方法がないことに驚きました。

Linuxの場合errnoが設定され、ferrorも使用できます。 Windowsではerrnoも設定されますが、MSDNにはferrorは記載されていません。


代わりに汚いが、ポータブルソリューションのためにこれを行うことができます:

int x,y; 
char d; 
if (sscanf(buffer, "START %d %d EN%c", &x, &y, &d) != 3 || 'D' != d) 
    return false; 
+0

'ferror'は' sscanf'とは無関係です。ファイルストリームから読み込まないためです。 –

+0

@JonathanWakely申し訳ありません。私は 'fscanf'のドキュメントを' sscanf'ではなく読んでいました。 – Simple

+0

あなたのソリューションは 'buffer'保留に失敗しました** START END ** –

0

は、私はいつものsscanf()と同様の機能面倒を使用することを発見した

int x, y; 
size_t pos = -1; 
char str[4]; 
if (sscanf(buffer, "START %d %d %3s%zn", &x, &y, str, &pos) != 3 || strcmp(pos, "END") || pos != strlen(buffer)) 
    return false; 
//... 
return true; 
1

試してみてください。他のソリューションははるかにエレガントですが、私はstrtok()に基づいてコードを維持するのが簡単で簡単です。 (最後にいくつかの空白行で)

#include <cstdio> 
#include <cstring> 

int main() 
{ 
    char buf[250]; 

    const char* delimiters=" \n"; 

    while(fgets(buf,250,stdin)!=nullptr){ 
     // fgets() reads the newline... 
     printf("%s",buf); 
     // Tokenize the buffer using 'delimiters'. The nullptr will re-use the same buffer. 
     char* pBegin = strtok(buf,delimiters); 
     char* pNumb1 = strtok(nullptr,delimiters); 
     char* pNumb2 = strtok(nullptr,delimiters); 
     char* pEnd = strtok(nullptr,delimiters); 
     // Protect our strcmp from a nullptr(missing data) and do some validity tests. 
     if((pEnd!=nullptr)&&(strcmp(pBegin,"BEGIN")==0)&&(strcmp(pEnd,"END")==0)){ 
      printf(" Begin = '%s'\n",pBegin); 
      printf(" Numb1 = '%s'\n",pNumb1); 
      printf(" Numb2 = '%s'\n",pNumb2); 
      printf(" End = '%s'\n",pEnd); 
     }else{ 
      printf(" Error!\n"); 
     } 
    } 
} 

そして、いくつかのテストデータ:ここで実験する小さなプログラムです

BEGIN 106 635 END 
BEGIN 107 636 END 
BEGaN 108 637 ENDING 
BeGIN 115 644 End 
BEGIN 116 645 END 
BEGIN 117 646 END of it all 
BEgIN 128 657 END 
BEGIN 129 658 END 
BEGIN 130 659 Finish 
131 660 END 
BEGIN 662 END 
BEGIN 136 665 
BEGIN 136 
BEGIN 

そして、これは出力になります...

BEGIN 106 635 END 
    Begin = 'BEGIN' 
    Numb1 = '106' 
    Numb2 = '635' 
    End = 'END' 
BEGIN 107 636 END 
    Begin = 'BEGIN' 
    Numb1 = '107' 
    Numb2 = '636' 
    End = 'END' 
BEGaN 108 637 ENDING 
    Error! 
BeGIN 115 644 End 
    Error! 
BEGIN 116 645 END 
    Begin = 'BEGIN' 
    Numb1 = '116' 
    Numb2 = '645' 
    End = 'END' 
BEGIN 117 646 END of it all 
    Begin = 'BEGIN' 
    Numb1 = '117' 
    Numb2 = '646' 
    End = 'END' 
BEgIN 128 657 END 
    Error! 
BEGIN 129 658 END 
    Begin = 'BEGIN' 
    Numb1 = '129' 
    Numb2 = '658' 
    End = 'END' 
BEGIN 130 659 Finish 
    Error! 
131 660 END 
    Error! 
BEGIN 662 END 
    Error! 
BEGIN 136 665 
    Error! 
BEGIN 136 
    Error! 
BEGIN 
    Error! 

    Error! 
関連する問題