char-as-number的格式字符串修饰符是什么?
我希望使用sscanf读取一个不超过255(实际上更少)的数字到无符号字符型变量。
使用典型的
char source[] = "x32";
char separator;
unsigned char dest;
int len;
len = sscanf(source,"%c%d",&separator,&dest);
// validate and proceed...
我收到了预期的警告:sscanf的参数4是char *类型,int *是预期的。
据我了解规格,char没有修饰符(比如%sd表示简短,或%lld表示64位长)
答案 0 :(得分:4)
您可以在glibc的scanf()
下使用%hhd
,MSVC似乎不直接支持整数存储到字符中(有关支持的转换的详细信息,请参阅MSDN scanf Width Specification)
答案 1 :(得分:1)
使用它是危险的。由于存在从unsigned char *到int *的隐式转换,如果该数字大于0xFF,它将使用堆栈中变量旁边的字节(最大3)并破坏它们的值。
%hhd的问题在于,根据int的大小(不一定是4个字节),它可能不是1个字节。
似乎sscanf不支持将数字存储到char中,我建议你使用int代替。虽然如果你想让char翻转,你可以在之后将int转换为char,如:
int dest;
int len;
len = sscanf(source,"%c%d",&separator,&dest);
dest = (unsigned char)dest;
答案 2 :(得分:0)
我想从未读过一个数字 超过255(实际上更少) 到unsigned char类型变量 使用sscanf。
在大多数情况下,通过使用char作为整数,您可以节省很少的东西。
它通常依赖于体系结构和编译器,但是大多数现代CPU在处理与寄存器大小不同的数据类型方面不是很好。 (值得注意的例外是64位arch上的32位int。)
在这里添加对非CPU字对齐的内存访问的惩罚(不要问我为什么CPU这样做)char的使用应限于真正需要char或内存消耗的情况。
答案 3 :(得分:0)
这是不可能的。
sscanf在读取整数时永远不会写单个字节。
如果将指向单个已分配字节的指针作为指向int的指针传递,则将超出范围。由于默认对齐,这可能是好的,但你不应该依赖它。
创建一个临时的。这样你也可以运行时检查它。
答案 4 :(得分:0)
最简单的方法可能是将数字简单地加载到一个临时整数中,并且只有当它在所需的边界内时才存储它。 (你可能需要像unsigned char result = tempInt & 0xFF;
)
答案 5 :(得分:0)
这很危险。 Scanf将在字符大小的变量上写入整数大小的值。在你的例子中(最有可能)除非你重组你的堆栈变量,否则什么都不会发生(scanf会在尝试写整数大小的“dest”时部分覆盖len,但是它会返回正确的“len”并用“right”值覆盖它)。
相反,做“正确的事”而不是依赖于编译器的情绪:
char source[] = "x32";
char separator;
unsigned char dest;
int temp;
int len;
len = sscanf(source,"%c%d",&separator,&temp);
// validate and proceed...
if (temp>=YOUR_MIN_VALUE && temp<=YOUR_MAX_VALUE) {
dest = (unsigned char)temp;
} else {
// validation failed
}