sscanf 忽略两个连续字符串中的第一个。我需要适当的格式字符串
sscanf ignores the first of two consecutive strings. I need the appropriate format string
输出的第一行是提供给如下所示的 sscanf 命令的输入字符串
其他行只是扫描值的打印值,arg1 和 arg2 分别是 args uint16_t 参数的高字节和低字节。
我不明白为什么没有扫描 id01 并将其分配给 packet.identifier。
我需要一个可以同时获取 id01 和 switch 的工作格式字符串。
另外,非常感谢对格式字符串的解释。
提前感谢您的帮助:)
#include <stdio.h>
#include <inttypes.h>
struct data_packet{
char identifier[8];
char command[8];
uint8_t arg1;
uint8_t arg2;
};
#define INPUT_STR "<<< id01 switch 0xAB29 >>>"
struct data_packet parse_input(char *input){
//uint8_t exit_code = 1;
struct data_packet packet;
uint8_t conversions = 0;
uint16_t args = 0;
conversions = sscanf(input , "<<< %s %s %x >>>", packet.identifier, packet.command, &args);
packet.arg1 = (args >> 8); // High Byte of args
packet.arg2 = (args & 0x00FF); //Low byte of args
//if (conversions == 3) exit_code = 0;
//return exit_code;
return packet;
}
int main(void){
struct data_packet data = parse_input(INPUT_STR);
printf("%s\n", INPUT_STR);
printf("identifier: %s\ncommand: %s\narg1: 0x%0x\narg2: 0x%0x\n", data.identifier, data.command, data.arg1, data.arg2);
return 0;
}
运行 代码通过 online compiler 我看到了警告:
main.c:17:46: warning: format ‘%x’ expects argument of type ‘unsigned int *’,
but argument 5 has type ‘uint16_t * {aka short unsigned int *}’ [-Wformat=]
conversions = sscanf(input , "<<< %s %s %x >>>", packet.identifier, packet.command, &args);
^
将声明更改为:
uint32_t args = 0;
它运行得很干净。
格式代码 %x
适用于 unsigned int
,而非 uint16_t
。格式说明符和参数类型不匹配导致 未定义的行为。
对于 uint16_t
使用来自 <inttypes.h>
header:
的 pre-defined 宏 SCNx16
sscanf(input , "<<< %s %s %" SCNx16 " >>>", packet.identifier, packet.command, &args);
可能发生的情况是,因为 unsigned int
通常是 32 位,所以 sscanf
函数会将这 32 位的一半写入您的其他变量之一。很可能 packet.identifier[0]
,它设置为零,恰好与字符串终止符相同。
如果您使用调试器查看 package.identifier
的实际内容,您可能会很快看到它。
并将此作为教训,始终 构建时启用额外的警告,并将它们视为 必须 修复的错误。
输出的第一行是提供给如下所示的 sscanf 命令的输入字符串
其他行只是扫描值的打印值,arg1 和 arg2 分别是 args uint16_t 参数的高字节和低字节。
我不明白为什么没有扫描 id01 并将其分配给 packet.identifier。
我需要一个可以同时获取 id01 和 switch 的工作格式字符串。 另外,非常感谢对格式字符串的解释。
提前感谢您的帮助:)
#include <stdio.h>
#include <inttypes.h>
struct data_packet{
char identifier[8];
char command[8];
uint8_t arg1;
uint8_t arg2;
};
#define INPUT_STR "<<< id01 switch 0xAB29 >>>"
struct data_packet parse_input(char *input){
//uint8_t exit_code = 1;
struct data_packet packet;
uint8_t conversions = 0;
uint16_t args = 0;
conversions = sscanf(input , "<<< %s %s %x >>>", packet.identifier, packet.command, &args);
packet.arg1 = (args >> 8); // High Byte of args
packet.arg2 = (args & 0x00FF); //Low byte of args
//if (conversions == 3) exit_code = 0;
//return exit_code;
return packet;
}
int main(void){
struct data_packet data = parse_input(INPUT_STR);
printf("%s\n", INPUT_STR);
printf("identifier: %s\ncommand: %s\narg1: 0x%0x\narg2: 0x%0x\n", data.identifier, data.command, data.arg1, data.arg2);
return 0;
}
运行 代码通过 online compiler 我看到了警告:
main.c:17:46: warning: format ‘%x’ expects argument of type ‘unsigned int *’,
but argument 5 has type ‘uint16_t * {aka short unsigned int *}’ [-Wformat=]
conversions = sscanf(input , "<<< %s %s %x >>>", packet.identifier, packet.command, &args);
^
将声明更改为:
uint32_t args = 0;
它运行得很干净。
格式代码 %x
适用于 unsigned int
,而非 uint16_t
。格式说明符和参数类型不匹配导致 未定义的行为。
对于 uint16_t
使用来自 <inttypes.h>
header:
SCNx16
sscanf(input , "<<< %s %s %" SCNx16 " >>>", packet.identifier, packet.command, &args);
可能发生的情况是,因为 unsigned int
通常是 32 位,所以 sscanf
函数会将这 32 位的一半写入您的其他变量之一。很可能 packet.identifier[0]
,它设置为零,恰好与字符串终止符相同。
如果您使用调试器查看 package.identifier
的实际内容,您可能会很快看到它。
并将此作为教训,始终 构建时启用额外的警告,并将它们视为 必须 修复的错误。