【问题标题】:fscanf get string between double quotes and numberfscanf 获取双引号和数字之间的字符串
【发布时间】:2021-10-20 19:43:00
【问题描述】:

fscanf 从未进入我的脑海...

我正在扫描 /proc/partinfo 并且需要从名称中获取分区号。 换句话说:

在一行中:

part22: 02200000 01000000 "kernel"

我需要获取“内核”(不带引号)和 22

到目前为止我做到了:

fscanf(fp,"%*5c%d%*c %*s %*s %s",&pnum,pname)

这给了我数字 22 和包含引号的“内核”。 如何不将它们包含在 scanfline 中?

我也不明白为什么 %*5c 有效,但应该是 %*4c 跳过“部分”字。

【问题讨论】:

    标签: c scanf


    【解决方案1】:

    scanf 系列函数被称为穷人的解析器,因为它们不是很强大,但可以扫描

    这里是你想要的:

    • 跳过任何一个数字
    • 读一个数字
    • 跳过双引号之前的任何内容
    • 跳过双引号
    • 阅读下一个双引号
    • 跳过双引号

    使用[] 转换,您可以编写:

    int cr = sscanf(input, "%*[^0-9]%d%*[^\"]\"%[^\"]\"", &pnum, pname);
    

    它对额外的初始空格很健壮,或者如果您在循环中读取到上一行的终止 \n

    注意:我使用cr = ... 是因为您应该始终控制输入函数的返回值...

    【讨论】:

    • 最后的“跳过双引号”几乎没有意义(如果您想阅读以下几行,则应将所有内容跳过到下一个换行符),好像缺少尾随的“,您可以”不知道。您还应该在%[ 上设置最大长度,否则它可能会溢出其缓冲区。
    • 没有这些问题。它是一款配置非常严格的嵌入式设备。此外,我最终在 python 中重新编码了嵌入在同一平台上且不需要编译的所有内容。在python中我最终做了: if(line.split(' ')[3].split('"')[1]=='kernel'): dev=line.split(' ')[0].strip (':').replace('part','/dev/mmcblk0p')
    【解决方案2】:
    char x[100] = {0}; // init not needed if you're careful enough with the return values
    fscanf(fp, " \"%[^\"]\"", x); // matches quotemark, then non-quotemark chars, then the closing quotemark
    // even better use e.g. %99[^\"] (i.e. bufsize-1) to prevent accidental buffer overrun
    printf("->%s<-\n", x);
    -->
    ->kernel<-
    

    如果您的那部分代码处于循环中,或者遵循您未显示的其他类似逻辑,则可能您未读取先前的换行符,并且%5*c 正在吃\n p a r t。也可能在part 之前有一个实际的字符,可能是一个不可见的字符;我没有任何带有/proc/partinfo 的系统要检查。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-08
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 2014-05-12
    • 1970-01-01
    相关资源
    最近更新 更多