在 Cppcheck 抱怨"%u"
扫描到int
变量的格式说明符错误之后,我将格式更改为"%d"
,但是在提交更改之前再次查看它时,我认为其目的可能是防止负面输入。我写了两个小程序来看看区别:
说明符 %d
#include <iostream>
#include <stdlib.h>
using namespace std;
int main() {
const char* s = "-4";
int value = -1;
int res = sscanf(s, "%d", &value);
cout << "value:" << value << endl;
cout << "res:" << res << endl;
return 0;
}
说明符 %u
#include <iostream>
#include <stdlib.h>
using namespace std;
int main() {
const char* s = "-4";
int value = -1;
int res = sscanf(s, "%u", &value);
cout << "value:" << value << endl;
cout << "res:" << res << endl;
return 0;
}
结果)
令人惊讶的是,两个转换说明符都接受了这个符号:
value:-4
res:1
我查看了 cppreference.com 上的文档。对于 C ( scanf, fscanf, sscanf, scanf_s, fscanf_s, sscanf_s - cppreference.com ) 以及 C++ ( std::scanf, std::fscanf, std::sscanf - cppreference.com ),"%u"
转换说明符的描述是相同(强调我的):
匹配无符号十进制整数。
数字的格式与 strtoul() 预期的格式相同,基本参数的值为 10。
观察到的行为标准是否合规?我在哪里可以找到这个文档?
[更新] 未定义的行为,真的,为什么?
我读到它只是 UB,好吧,为了增加混乱,这里是将值声明为unsigned
https://ideone.com/nNBkqN的版本- 我认为分配-1
仍然是预期的,但是 "%u" 显然仍然匹配符号:
#include <iostream>
#include <stdlib.h>
using namespace std;
int main() {
const char* s = "-4";
unsigned value = -1;
cout << "value before:" << value << endl;
int res = sscanf(s, "%u", &value);
cout << "value after:" << value << endl;
cout << "res:" << res << endl;
return 0;
}
结果:
value before:4294967295
value after:4294967292
res:1