使用带有可选空格的sscanf进行格式化输入

时间:2014-10-11 22:14:28

标签: c scanf

我试图从字幕文件(STL格式)中读取字符串格式的输入:

1)00:00:37:09 , 00:00:39:24 , Subtitle Text.(即空格和时间和文字的空格)

相同字幕格式的另一种格式是

2)00:00:31:02,00:00:33:00,Subtitle Text.(即没有时间和文字的任何空格)

要阅读我正在执行以下操作的行:

sscanf(*buf, "%2d:%2d:%2d:%2d , %2d:%2d:%2d:%2d , %n",
&hh1, &mm1, &ss1, &ms1, &hh2, &mm2, &ss2, &ms2, &len)

但是,如果字幕文件混合了1)和2),或者如果文件具有其他空格组合,则读取文本错误。我应该如何阅读输入以忽略空格?

2 个答案:

答案 0 :(得分:1)

如上面的答案中所述,最好提供完整的代码,以及您使用的OS和devkit,因为可能存在差异。我在Linux上使用标准的cc编译器尝试了你的代码,发现没有错误引起输入字符串(我在buf之前删除了*,因为我认为它不是任何间接的。)

我的建议: 如果您无法控制确切的输入格式,请不要使用sscanf()!至少如果你想创建一个稳定的应用程序。

答案 1 :(得分:0)

假设bufchar **buf的变体(指向char的双指针),代码应该没问题 - 只要你的'毫秒'字段(从使用中推断) &ms1&ms2作为变量名称)从不超过2位数。显式出现在格式字符串中的空格意味着“可选的空格”。在%2d之前技术上是多余的,但没有任何伤害。

您的片段有一个左括号和两个近括号。我认为这意味着你在以下环境中使用它:

int rc;
if ((rc = sscanf(…)) != 8)
    …oops — malformatted data…
else
    …pick up subtitle from `(*buf)[len]` onwards…

如果遇到问题,则需要显示导致问题的数据。您可以在我在伪代码片段中编写oops — malformatted data的位置打印它:

if ((rc = sscanf(…)) != 8)
{
    fprintf(stderr, "Malformatted data (rc = %d): <<%s>>\n", rc, *buf);
}
else
{
    …pick up subtitle from `(*buf)[len]` onwards…
}

我使用rc作为“返回代码”的简称。


演示

#include <stdio.h>

int main(void)
{
    char *data[] =
    {
        "00:00:37:09 , 00:00:39:24 , Subtitle Text 1",
        "00:00:31:02,00:00:33:00,Subtitle Text 2",
    };

    for (size_t i = 0; i < sizeof(data)/sizeof(data[0]); i++)
    {
        int hh1, mm1, ss1, ms1;
        int hh2, mm2, ss2, ms2;
        int len;
        int rc;
        char **buf = &data[i];

        if ((rc = sscanf(*buf, "%2d:%2d:%2d:%2d , %2d:%2d:%2d:%2d , %n",
                         &hh1, &mm1, &ss1, &ms1, &hh2, &mm2, &ss2, &ms2, &len)) != 8)
        {
            fprintf(stderr, "Malformatted data (rc = %d): <<%s>>\n", rc, *buf);
        }
        else
        {
            char *subtitle = (*buf) + len;
            printf("%.2d:%.2d:%.2d.%.2d - %.2d:%.2d:%.2d.%.2d = [%s]\n",
                   hh1, mm1, ss1, ms1, hh2, mm2, ss2, ms2, subtitle);
        }
    }
    return 0;
}

输出:

00:00:37.09 - 00:00:39.24 = [Subtitle Text 1]
00:00:31.02 - 00:00:33.00 = [Subtitle Text 2]