Парсинг с пробелом (sscanf или strtok)

В некотором контексте моя игра запускается в терминале и похожа на игру типа командной строки. На данный момент для обработки команд используется strcmp() для каждой отдельной команды, что не очень красиво и неэффективно. Из-за этого я решил, что надо переделать. Я попробовал просмотреть другие посты и не нашел ничего полезного. Я хочу, чтобы он сохранял каждый раздел команды. Например:

    //let's just say command = "debug test"
    char part1;
    char part2;

    split via " "

    part1 = "debug"
    part2 = "test"

Я пытался использовать sscanf(), но это просто оборвало бы строку. Например, предположим, что я дал ему строку «тест». Это выведет: test -> est -> st //and so on

🤔 А знаете ли вы, что...
C обеспечивает возможность создания пользовательских типов данных и структур.


2
75
1

Ответ:

Решено

Вот минимальное решение с использованием sscanf():

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

#define PART_LEN 5
#define str(s) str2(s)
#define str2(s) #s

int main() {
    char command[] = "debug test";
    char part1[PART_LEN+1] = "";
    char part2[PART_LEN+1] = "";
    int r = sscanf(command, "%" str(PART_LEN) "s%" str(PART_LEN) "s", part1, part2);
    if (r != 2) {
        // handle partial input
    }
    printf("part=%s part2=%s\n", part1, part2);
}

Ключевое понимание:

  1. Переменные, состоящие из двух частей, должны представлять собой массивы char [] соответствующего размера, в которых sscanf() могут храниться копии строк.
  2. Всегда используйте максимальную ширину поля при чтении строк с помощью scanf()-семейства функций.
  3. Обработка неполного ввода (r != 2). В этом случае я инициализировал две части пустой строкой.

и вот аналогичное решение с strtok():

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

#define DELIM " "

int main() {
    char command[] = "debug test";
    char *part1 = strtok(command, DELIM);
    char *part2 = strtok(NULL, DELIM);
    printf("part=%s part2=%s\n", part1 ? part1 : "", part2 ? part2 : "");
}

Ключевое понимание:

  1. Переменная command должна иметь тип char [], а не char *, поскольку strtok() изменяет строку.
  2. При первом вызове strtok() в качестве первого аргумента ожидается строка, а при последующих вызовах — NULL.
  3. part1 и/или part2 может иметь значение NULL, в этом случае токены не найдены.

Третий вариант — реализовать функцию split() для возврата массива найденных строк. См. Разделение строки с разделителями в C