Как найти строку с неизвестным количеством слов? - PullRequest
1 голос
/ 25 января 2020

У меня есть текстовый файл, отформатированный так:

код имя-субъекта ects

Где code и ects являются целые числа, subject_name - строка, которая может содержать несколько слов и иногда содержит число.

Я пробовал fscanf(f, "%d %s %d", &code, subject_name, &ects);, который не работает, поскольку в строке есть пробелы .

"%d %[^\n] %d" также не будет работать, потому что строка глотает ects .

Как правильно это сделать?

1 Ответ

0 голосов
/ 26 января 2020

Шаг 1: читать строку

#define LINE_MAX_EXPECTED_SIZE 100
char buf[LINE_MAX_EXPECTED_SIZE + 2];// Let code read lines that are too long

if (fgets(buf, sizeof buf, f)) {
  buf[strcspn(buf, "\n\r")] = '\0';  // lop off potential end-of-line
  if (strlen(buf) >= LINE_MAX_EXPECTED_SIZE || buf[0] == '\0') {
    fprintf(stderr, "Line too long/short. <%s>\n", buf); 
    exit(EXIT_FAILURE);
  }
  ...

ОК, теперь у нас есть строка , считанная и сохраненная как строка .

Шаг 2: Поскольку subject_name и ects могут быть числами, пусть код сначала ищет ects, поскольку это одно и только одно число.

  // Start at end
  char *end = strlen(buf) - 1;
  if (!isdigit((unsigned char) *end)) {
    fprintf(stderr, "No number at end. <%s>\n", buf); 
    exit(EXIT_FAILURE);
  }
  while (end > buf && isdigit((unsigned char) * --end)) {
    ;
  }
  if (end > buf && (*end == '-' || *end == '+')) {
    end--;
  }
  ects = atoi(end + 1); // or better strtol()
  end[1] = '\0'; // lop off ects

Теперь buf имеет, надеюсь, code и subject_name, которые можно проанализировать с помощью кода пользователя, sscanf(), strtol() и т. Д. c. Оставьте это для ОП.

...