Как я могу использовать функцию sscanf для чтения определенных символов? - PullRequest
1 голос
/ 13 марта 2019

Я хочу прочитать информацию из файла и присвоить значению a в файле значение «a», а значение b - «b».Но это не сработало.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
    FILE *fp;
    char buffer[1024];
    char zahla[128];
    char zahlb[128];
    char zimu[128];

    fp = fopen("./0312.conf", "r");
    if (fp == NULL) {
        perror("error");
        return (-1);
    }
    while (fgets(buffer, 1024, fp) != NULL) {
        sscanf(buffer, "%^", zimu);
        printf("zimu is: %s\n", zimu);

        if (strcmp(zimu, "a") == 0) {
            sscanf(buffer, "%[1-9]s", zahla);
        }
        if (strcmp(zimu, "b") == 0) {
            sscanf(buffer, "%[1-9]s", zahlb);
        }
    }
    printf("a=%s, b=%s\n", zahla, zahlb);
}

содержимое файла:

       a=10
                b=5

Ответы [ 2 ]

2 голосов
/ 13 марта 2019
  • Спецификатор формата "%^" не имеет смысла и фактически ничего не сделает - поэтому вы никогда ничего не получите в своем массиве zimu.

  • s после %[1-9] в спецификаторе формата означает «соответствовать символу литерала», поэтому никогда не будет совпадать. Вы, вероятно, просто хотите удалить его.

  • Поскольку строки ввода начинаются с a= или b=, спецификаторы формата "%[1-9]" не будут совпадать.

Скорее всего, вы хотите что-то вроде

char name[100], value[100];
if (sscanf(buffer, " %99[a-z] = %99[0-9]", name, value) == 2) {
    // matched a line with name=value, do something with it
} else {
    // didn't match -- give an error?
}
  • используйте пробелы в формате для пропуска пробелов - при наличии пробела пропускается более 0 или более пробелов. Обратите внимание на 0 - пробел не требуется, и может быть любое количество пробелов
  • ВСЕГДА проверяйте возвращаемое значение, чтобы увидеть, соответствует ли ожидаемое количество элементов
  • Вам нужно что-то в формате, чтобы соответствовать всем символам в строке, хотя спецификаторы формата, кроме %[ и %c, также будут пропускать пробелы, и вы можете игнорировать завершающие элементы, если вас это не волнует. Если вам небезразличен конечный результат, вы можете использовать %n, чтобы проверить, сколько символов вы отсканировали, чтобы убедиться, что это вся строка.
  • использовать границы для спецификаторов %s и %[, считывающих фиксированные массивы, чтобы гарантировать, что они не переполняются.
0 голосов
/ 13 марта 2019

Существует некоторая путаница в отношении наборов сканирования %[abc] в строках формата scanf: необходимо указать максимальное количество символов для чтения и указать диапазон символов от [ до ].Трейлинг s после ] отсутствует.Из-за лишних пробелов в строке формата пробелы пропускаются.

Вот исправленная версия вашего кода.

#include <stdio.h>
#include <string.h>

int main() {
    FILE *fp;
    char buffer[1024];
    char zimu[128];
    char zahla[128];
    char zahlb[128];

    fp = fopen("./0312.conf", "r");
    if (fp == NULL) {
        perror("error");
        return -1;
    }
    zahla[0] = zahlb[0] = '\0';
    while (fgets(buffer, 1024, fp) != NULL) {
        if (sscanf(buffer, " %127[a-z]", zimu) != 1)
            continue;
        printf("zimu is: %s\n", zimu);
        if (strcmp(zimu, "a") == 0) {
            sscanf(buffer, " a = %127[1-9]", zahla);
        }
        if (strcmp(zimu, "b") == 0) {
            sscanf(buffer, " b = %127[1-9]", zahlb);
        }
    }
    printf("a=%s, b=%s\n", zahla, zahlb);
    return 0;
}
...