Преобразование буфера в массив символов для strtok - PullRequest
0 голосов
/ 04 февраля 2019

У меня возникли некоторые проблемы с использованием системных вызовов в C. Я пытаюсь использовать read для чтения некоторых входных данных из stdin, а затем использовать strtok для загрузки значений в массив, но я не могу этого сделатьэто верно (я продолжаю получать segfault).

Вот код, с которого я начал:

void read_input()
{
    char* c;
    read(0, c, 128);
    printf("%s", c);
}

Итак, все работает отлично, и я могу напечатать вывод.Тем не менее, я попробовал несколько вещей дальше, и они не сработали.Я пытался:

  1. Создание массива char arr[128], затем с использованием различных вариантов strcpy, strncpy и memcpy для копирования c в arr, но у них нетне сработало, и я получил ошибку.

Собственно, это все, что я пробовал.Я не уверен, как я должен скопировать c в arr, чтобы я мог использовать strtok.Кто-нибудь может объяснить?

Спасибо

Редактировать:

Ладно, это мой новый код:

void
read_input()
{
    char arr[129];
    int r = read(0, arr, 129);
    printf("%s", arr);

    arr[r] = '\0';

    char* pch;

    pch = strtok(arr, " \n");

    while(pch != NULL)
    {
        printf("%s\n", pch);
        pch = strtok(NULL, " \n");
    }
}

Я пытаюсь прочитать из стандартного вводавведите как "привет, меня зовут Джон".Вот вывод, который я получаю из printfs:

hi my name is john
�����hi
my
name
is
john

Почему первый токен выглядит так?Я заметил, что если я не добавлю arr[r] = '\0', то «Джон» будет выглядеть как «Привет».Что мне нужно сделать для первого персонажа, похожего на последний?

Ответы [ 2 ]

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

Ваша вторая программа не работает, потому что вы ставите NUL терминатор после вызова printf.Вам нужно сделать это до printf:

char arr[129];              // 128 + 1 for the NUL terminator
int r = read(0, arr, 128);
arr[r] = '\0';
printf("%s\n", arr);        // \n for better readbility of the output

Вам также нужен еще один байт для терминатора NUL, следовательно, 129.

printf со спецификатором формата %s печатает NUL завершенные строки.Поскольку вы не ставите NUL перед printf, последний отображает все символы до тех пор, пока не встретит NUL, следовательно, вы получите вывод:

hi my name is john
�����
...

Этот вывод может отличаться, это зависит отпредыдущее содержимое буфера arr.

Первая версия неверна, поскольку указатель c не инициализирован, он нигде не указывает.В этом случае программа может работает корректно, но это так называемое «неопределенное поведение», Google и имейте в виду, что «неопределенное поведение» включает в себя «очевидно, работает нормально».

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

Вы можете напрямую перейти к этому:

void read_input()
{
    char arr[128];
    read(0, arr, 128);
    printf("%s", arr);
}

Или маршрут динамического выделения памяти:

char *arr = malloc((sizeof(*arr) * 128) + 1);
if (arr == NULL)
{
    // handle error
}
int r = read(0, arr, 128);
arr[r] = '\0';
printf("%s", arr);
...