动态限制 sscanf 中考虑的字符数?
dynamically limit the number of chars considered in sscanf?
(上下文,感谢评论:我需要解析一个较长字符串的子字符串。子字符串的长度直到运行时才知道,并且封闭的字符串是只读的,所以写一个空终止符出来了。因为它在嵌入式系统上,malloc()
不存在并且堆栈大小有限。)
考虑以下代码段,它将 sscanf()
转换限制为“1234”的前两个字符:
int d;
sscanf("1234", "%2d", &d); // => 12
但是,如果您需要动态地动态设置该限制(例如,对于非空终止的输入字符串)怎么办?如果它类似于printf()
,你可以这样做:
int d;
int len = 2;
sscanf("1234", "%*d", len, &d); // doesn't work
这没有按预期工作,因为 *
修饰符意味着跳过下一个参数。
我想出的最好办法是使用 sprintf() 动态生成 sscanf()
的格式字符串:
char fmt[5];
int d;
int len = 2;
snprintf(fmt, sizeof(fmt), "%%%dd", len); // fmt = "%2d"
sscanf("1234", fmt, &d);
Temple of Godbolt 告诉我这行得通。但是也许有一种不那么折磨人的方法吗?
更新
感谢@Shawn 的精神推动,我意识到尽管我正在使用的子字符串的长度是可变的,但它 有一个最大长度限制。所以我可以完全放弃 scanf() ,按照:
char buf[MAX_SUBSTRING_LENGTH];
memcpy(buf, pointer_to_substring, substring_length);
int d = atoi(buf);
你所拥有的几乎是你唯一的选择。
如您所见,scanf
格式说明符不允许通过单独的参数指定字段宽度,这与 printf
格式说明符不同。
因此,您构造格式字符串的方式实际上是动态设置 scanf
格式宽度的唯一方式。
(上下文,感谢评论:我需要解析一个较长字符串的子字符串。子字符串的长度直到运行时才知道,并且封闭的字符串是只读的,所以写一个空终止符出来了。因为它在嵌入式系统上,malloc()
不存在并且堆栈大小有限。)
考虑以下代码段,它将 sscanf()
转换限制为“1234”的前两个字符:
int d;
sscanf("1234", "%2d", &d); // => 12
但是,如果您需要动态地动态设置该限制(例如,对于非空终止的输入字符串)怎么办?如果它类似于printf()
,你可以这样做:
int d;
int len = 2;
sscanf("1234", "%*d", len, &d); // doesn't work
这没有按预期工作,因为 *
修饰符意味着跳过下一个参数。
我想出的最好办法是使用 sprintf() 动态生成 sscanf()
的格式字符串:
char fmt[5];
int d;
int len = 2;
snprintf(fmt, sizeof(fmt), "%%%dd", len); // fmt = "%2d"
sscanf("1234", fmt, &d);
Temple of Godbolt 告诉我这行得通。但是也许有一种不那么折磨人的方法吗?
更新
感谢@Shawn 的精神推动,我意识到尽管我正在使用的子字符串的长度是可变的,但它 有一个最大长度限制。所以我可以完全放弃 scanf() ,按照:
char buf[MAX_SUBSTRING_LENGTH];
memcpy(buf, pointer_to_substring, substring_length);
int d = atoi(buf);
你所拥有的几乎是你唯一的选择。
如您所见,scanf
格式说明符不允许通过单独的参数指定字段宽度,这与 printf
格式说明符不同。
因此,您构造格式字符串的方式实际上是动态设置 scanf
格式宽度的唯一方式。