C++ 使用sscanf c+检查格式并获取数字+;
我需要检查一个字符数组以获得一种特定的简单格式,并同时获取其中两个数字的值。消息格式为:开始号码结束。我所能想到的就是:C++ 使用sscanf c+检查格式并获取数字+;,c++,scanf,C++,Scanf,我需要检查一个字符数组以获得一种特定的简单格式,并同时获取其中两个数字的值。消息格式为:开始号码结束。我所能想到的就是: int x,y; if ( sscanf(buffer, "START %d %d END", &x, &y) != 2) return false; ... ... ... return true; 但这当然成功了,即使结局完全不同,因为数字是获得的。最好的方法是什么?谢谢你的建议。在检查了C标准之后,我很惊讶没有便携式的方法来检测这一点 在Li
int x,y;
if ( sscanf(buffer, "START %d %d END", &x, &y) != 2)
return false;
...
...
...
return true;
但这当然成功了,即使结局完全不同,因为数字是获得的。最好的方法是什么?谢谢你的建议。在检查了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;
试一试
我总是觉得使用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 = '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!
看起来你把缓冲区的内容和字符串“START%d%d END”弄混了。sscanf需要一个包含您的字符串的缓冲区和一个包含格式数据的第二个字符串,即
sscanf(“开始9 10结束”,%s%d%d%s),buff1,&x,&y,buff2)
。您想做什么?使用格式化字符串“START%d%d”调用sscanf,如果一切正常,则使用格式化字符串“%s”调用sscanf,并将结果与“END”进行比较。@auburg,格式数据是“START%d%d END”
,即字符串必须包含这些普通字符。在scanf格式中使用%s是危险的,应始终避免使用,如果使用%5s和%3s,您的建议就可以了。@user121270,请参阅上面的注释,%s是危险的,如果您使用%3s并传递指向至少4字节数组的指针,您的建议就可以了。ferror
与sscanf
无关,因为它不从文件流读取。@JonathanWakely很抱歉,我正在阅读fscanf
非sscanf
的文档。您的解决方案因缓冲区而失败。
按住START-END我已经保证结束后不会有任何内容,因此这个解决方案对我来说非常有效。
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!