动态限制 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 格式宽度的唯一方式。