Поиск и печать последнего слова строки с разделителем пробела или табуляции - PullRequest
0 голосов
/ 17 февраля 2019

Я пытаюсь получить последнее слово строки как параметр argv в C. Как найти последнее слово и разделить строки, содержащие пробел / табуляцию?

Определениеслова - это «часть строки, разделенная пробелами / символами табуляции или началом / концом строки.» Я изначально создал функцию для определения, что это пробел или символ табуляции;однако решение, которое я имею, подходит не для всех случаев.Большинство из них работает, но когда у моего argv есть строка типа "asdkBakjsdhf1785 ", ожидаемый результат должен быть "asdkBakjsdhf1785", а не "asdkBakjsdhf1785 ".Все эти функции должны быть сделаны с нуля, и мне разрешено использовать только функцию write из библиотеки <unistd.h>.

int my_isspace(char c)
{
    if (c == ' ' || c == '\t')
        return (1);
    return (0);
}

void    my_putstr(char *str)
{
    while (*str)
        write(1, str++, 1);
}

void    last_word(char *str)
{
    char *last;
    int i;

    i = 0;
    last = &str[i];
    while (str[i])
    {
        if (my_isspace(str[i]))
        {
            if (str[i + 1] >= '!' && str[i + 1] <= '~')
                last = &str[i + 1];
        }
        i++;
    }
    if (last)
        my_putstr(last);
}

int     main(int argc, char *argv[])
{
    if (argc == 2)
       last_word(argv[1]);
    my_putstr("\n");
    return (0);
}

На данный момент она выполняет анализ черезстрока и проверяет наличие пробела / табуляции.Если это так, он будет игнорировать его и переходить к следующему персонажу, пока не попадет в персонажа в диапазоне от ! до ~ (включая те).Как только он попадет к любому из символов между ними, он сохранит синтаксический анализ в другом пустом указателе строки, чтобы сохранить то, что было «последним словом».С помощью способа, которым я пользуюсь, где я могу улучшить немного, чтобы разделить мое пространство / табуляцию в конце?

1 Ответ

0 голосов
/ 17 февраля 2019

У вас есть пара проблем.Во-первых, это поможет сделать ваш my_isspace() приблизительно эквивалентным isspace(), чтобы он правильно рассматривал концы строк и как пробел, например,

int my_isspace (const char c)
{
    if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
        return 1;

    return 0;
}

Затем вы можете сделать last_word() (и многие другие).другие аналогичные функции классификации) намного проще, если использовать подход State Loop и оставить простой флаг, чтобы помочь вам с вашей классификацией.Например, здесь помогает узнать, читаете ли вы слово или нет.Это поддается простому состоянию входа / выхода, которое можно отслеживать с помощью простого флага int in = 0; за пределами слова и in = 1; внутри слова.

Если вы используете это, ваш last_word() можно записать для изменяемых строк следующим образом (аргументы для main() являются изменяемыми):

void last_word (char *str)
{
    char *p = NULL,     /* your last */
        *ep = NULL;     /* end pointer to end of last */
    int in = 0;         /* flag - in/out of a word */

    while (*str) {                  /* loop over each char */
        if (my_isspace (*str)) {    /* if a space */
            if (in)                 /* if in a word */
                ep = str;           /* set endptr to current char */
            in = 0;                 /* set out of word */
        }
        else {                      /* not a space */
            if (!in)                /* if not in a word */
                p = str;            /* set start pointer */
            in = 1;                 /* set in word */
        }
        str++;          /* increment pointer */
    }

    if (p) {            /* if we have start of word */
        if (ep)         /* if we have endptr set */
            *ep = 0;    /* nul-terminate at endptr */
        my_putstr (p);  /* output last */
    }
}

( note: если вы имеете дело с вводом не изменяемой строки, вы могли быиспользуйте ep - p, чтобы получить количество символов для вывода и выводить их по одному за раз)

Полный пример (с несколькими очистками) может быть:

#include <unistd.h>

int my_isspace (const char c)
{
    if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
        return 1;

    return 0;
}

void my_putstr (const char *str)
{
    size_t n = 0;

    for (n = 0; str[n]; n++) {}

    write (1, str, n);
}

void last_word (char *str)
{
    char *p = NULL,     /* your last */
        *ep = NULL;     /* end pointer to end of last */
    int in = 0;         /* flag - in/out of a word */

    while (*str) {                  /* loop over each char */
        if (my_isspace (*str)) {    /* if a space */
            if (in)                 /* if in a word */
                ep = str;           /* set endptr to current char */
            in = 0;                 /* set out of word */
        }
        else {                      /* not a space */
            if (!in)                /* if not in a word */
                p = str;            /* set start pointer */
            in = 1;                 /* set in word */
        }
        str++;          /* increment pointer */
    }

    if (p) {            /* if we have start of word */
        if (ep)         /* if we have endptr set */
            *ep = 0;    /* nul-terminate at endptr */
        my_putstr (p);  /* output last */
    }
}

int main (int argc, char **argv) {

    my_putstr ("'");
    if (argc >= 2)
        last_word (argv[1]);
    my_putstr ("'");
    my_putstr ("\n");

    return 0;
}

Пример Использование / Вывод

Одно слово:

$ ./bin/write_last_argv1 "fleas"
'fleas'

Одно слово с конечным пробелом:

$ ./bin/write_last_argv1 "fleas      "
'fleas'

Несколько слов:

$ ./bin/write_last_argv1 "my dog has fleas"
'fleas'

Несколько слов с начальным, конечным и несколькими пробелами:

$ ./bin/write_last_argv1 "  my    dog  has fleas   "
'fleas'

Просмотрите все и дайте мне знать, если у вас есть дополнительные вопросы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...