使用sscanf c ++

时间:2016-04-08 11:18:33

标签: c++ scanf

我需要检查特定简单格式的字符数组,并同时获取其中两个数字的值。消息格式为: START号码END 。我能想到的就是:

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

但是,即使在结尾完全不同之后,这当然也会成功,因为获得了数字。最好的方法是什么?谢谢你的建议。

3 个答案:

答案 0 :(得分: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;

答案 1 :(得分:1)

我总是发现使用sscanf()和类似功能很麻烦。虽然其他解决方案更优雅,但我更喜欢基于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!

答案 2 :(得分:0)

尝试

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;