C - scanf 仅在特定的字符序列之后在引号中提取数字

C - scanf to pull a number in quotes only after a specific sequence of characters

假设我有这样一个字符串:

Hello World - this is a line of textCOLOR="4"

并且这个字符串存储在buf[1000]

如您所见,该字符串具有 COLOR="n" 格式的颜色标签。该数字是需要提取的(可以在 1 到 56 之间)并分配给 int 变量。我希望此标记能够位于字符串中的任何位置。

我可以运行下面的代码提取颜色值:

int colorNumber = 1; //default value
if (scanf(buf, "%*[^\"]\"%2d[^\"]\"", &colorNumber)) {
    // work with number
}

这工作正常,但如果字符串中包含数字或引号,则 scanf 将无法生成数字。

我已经尝试了我的第二个 scanf 参数的一些变体,但这些都不起作用。我尝试了 "%*[^\"]COLOR=\"%2d[^\"]\"",但这似乎根本不起作用。

我已经查看了 scanf 的手册页,但我也找不到我要找的东西。

也许 scanf 不是正确的工具?如有必要,我愿意尝试其他libraries/functions。

尝试

if (sscanf(buf, "%*[^C]COLOR=\"%d", &colorNUM) == 1)

您尝试的 "%*[^\"]COLOR"... 格式无效的原因是 %*[\"] 匹配 " 之前的所有内容,跳过了 COLOR,因此会失败匹配颜色。但是,如果 COLOR 之前的字符串中还有另一个 C 其他地方,则上述操作将失败。为避免这种情况,您最好使用 strstr,如果 COLOR 可能出现在多个位置,则可能在循环中。

for (const char *p = buf; p = strstr(p, "COLOR"); ++p) {
    if (sscanf(p, "COLOR=\"%d", &colorNum) == 1) {
        // found a color number

另请注意,尝试匹配 %d 之后的字符是没有意义的,无论它们是否匹配,返回的值都是相同的,因此无法判断。如果你想确保数字后面有一个 ",你需要像

这样的东西
int end = 0;
if (sscanf(p, "COLOR=\"%d\"%n", &colorNum, &end), end > 0)

通过检查 %n 是否向 end 写入了内容,您还检查了 %n 之前的所有内容是否正确匹配。