sscanf可选列

时间:2012-02-16 11:16:35

标签: c gcc

我希望使用sscanf来读取具有以下格式的数据的文件,其中一个重要标准“Furtherdata”是可选的。

aidsomedatafurtherdata

sscanf(currentline[i], "%[^\t] %[^\t] %11 [^\n]", aIDVar, someDataVar, furtherDatVar) ==  3  

有没有办法做到这一点谢谢?

2 个答案:

答案 0 :(得分:3)

您通常可以通过检查*scanf的返回值来确保扫描参数的数量正确,类似于以下完整程序:

#include <stdio.h>

static void testFn (char *str) {
    int var1, var2, var3;

    if (sscanf(str, "%d %d %d", &var1, &var2, &var3) !=  3) {
        var3 = 42;
        if (sscanf(str, "%d %d", &var1, &var2) !=  2) {
            var1 = var2 = var3 = -1;
        }
    }
    printf ("[%-10s] -> %3d %3d %3d\n", str, var1, var2, var3);
}

int main (void) {
    testFn ("");
    testFn ("1");
    testFn ("1 2");
    testFn ("1 2 3");
    testFn ("1 2 3 4");

    return 0;
}

输出显示您需要两个带有可选第三个参数的参数:

[          ] ->  -1  -1  -1
[1         ] ->  -1  -1  -1
[1 2       ] ->   1   2  42
[1 2 3     ] ->   1   2   3
[1 2 3 4   ] ->   1   2   3

您需要根据您的特定数据进行调整,但这是基本理论。首先尝试更大的数量,如果这样做不好,请尝试使用默认值较低的数量。


附录:

正如ugoren在评论中指出的那样,*scanf在这种情况下不需要重复。事实上,对于像fscanf这样的东西,如果文件指针在第一次尝试后移动了,就会出现问题。

因为指令是按顺序处理的,所以你可以只存储返回值并重复使用它 - 前两个指令已经被操作(存储到var1var2)之前就失败了第三个%dtestFn函数可以重写为:

static void testFn (char *str) {
    int quant, var1, var2, var3;

    if ((quant = sscanf(str, "%d %d %d", &var1, &var2, &var3)) !=  3)
        if (quant ==  2)
            var3 = 42;
        else
            var1 = var2 = var3 = -1;
    printf ("[%-10s] -> %3d %3d %3d\n", str, var1, var2, var3);
}

答案 1 :(得分:0)

除了绝对琐碎的输入外,fgets通常是比scanf更好的工具。这并不难:

void input(char *str){
    int x, vars[3];
    char *sp;
    for(x=0,sp=strtok(str, " \t");x<3&&sp; x++,sp=strtok(NULL, " \t")){
          vars[x] = atoi(sp);
    }
    if(x<3) //didn't read enough
       //..deal with it
    if(sp) //your optional field is present
       //deal with that.
}