необязательный столбец sscanf - PullRequest
0 голосов
/ 16 февраля 2012

Я хочу использовать sscanf для чтения файла с данными, который имеет следующий формат с одним важным критерием «дальнейшие данные» является необязательным.

aidsomedatafuturedata

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

Есть ли способ сделать это спасибо?

Ответы [ 2 ]

3 голосов
/ 16 февраля 2012

Обычно это можно сделать, проверив возвращаемое значение *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

Вам нужно будет адаптировать это к вашим конкретным данным, но это основная теория. Сначала попробуйте большее количество и, если это не хорошо, попробуйте меньшее количество со значениями по умолчанию.


Добавление:

Как указывает Угорен в комментарии, *scanf не нужно повторять в этом сценарии. Фактически, это было бы проблематично для чего-то вроде fscanf, когда указатель файла переместился бы после первой попытки.

Поскольку директивы обрабатываются последовательно, вы можете просто сохранить возвращаемое значение и использовать его повторно - первые две директивы уже были бы применены (сохранены в var1 и var2) до сбоя в третьей %d , Функцию testFn можно переписать так:

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);
}
0 голосов
/ 16 февраля 2012

Помимо абсолютно тривиального ввода, 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.
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...