Использование strtok и попытка сохранить их значения в массиве - PullRequest
1 голос
/ 01 мая 2020

Я довольно новичок в C, и я пытался что-то, но это, кажется, не работает: у меня есть массив char *initialParts;, и я выделяю пространство в соответствии с вводом пользователя, но я не думаю, что это действительно важно. У меня также есть счетчик initialPartsCounter = 0;, который я использую в качестве индекса, чтобы при каждом индексе выделенной памяти я сохранял в нем букву. Пока что у меня есть это:

            char *initialParts;
            const char comma[3] = ",";
            int initialPartsCounter = 0;
            initialParts = (char*)malloc((int)numInitialParts * sizeof(char));
            char *token;
            token = strtok(fileLine, comma);

            while (token != NULL) {
                strcpy(&initialParts[initialPartsCounter], token);
                initialPartsCounter++;
                token = strtok(NULL, comma);
            }

            for (int l = 0 ; l < (int)numInitialParts; l++)
            {
                printf("%c", initialParts[l]);
            }

, где numInitialParts - это число, введенное пользователем, а fileLine - это строка, прочитанная в файле. В следующем примере numInitialParts = 4, and fileLine = 'q,d,c,k' В моем для l oop напечатанный вывод выглядит странно: qdck☐☐☐☐ (Я не мог скопировать символы после k, потому что он ничего не делал, когда я вставил его но что-то похожее, проверьте пи c, чтобы увидеть, как это выглядит).

enter image description here

РЕДАКТИРОВАТЬ: Мой идеальный вывод будет:

qdck

Если у кого-нибудь есть идея, чтобы решить эту проблему, я буду рад ее услышать. Спасибо!

Ответы [ 2 ]

0 голосов
/ 01 мая 2020

Поскольку вы печатаете

printf("%c", initialParts[l]);

Я могу предположить, что initialParts определяется как char *, а затем динамически распределяется.

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

strcpy(&initialParts[initialPartsCounter], token);

вы копируете в массив char как минимум два символа: символ токена (например, 'q') и терминатор строки '\0' (строка является просто массивом символов с нулевым символом в конце, и все функции манипулирования строк полагаются на него).

Просто выполните

initialParts[initialPartsCounter] = *token;

Действительно, это была не главная ошибка. Фактически, даже несмотря на то, что он показывает некоторое недопонимание того, как работает strtok, он будет работать до тех пор, пока в массиве initialParts не останется места для хранения текущего символа и ограничителя строки.

Другая ошибка заключается в том, что хотя при разборе strtok вы получаете только initialPartsCounter символов, но вы печатаете все символы массива (numInitialParts). Те, что в конце, будут бессмысленными, поэтому исправляя его, код будет работать, как и ожидалось.

В следующем примере ваш код встроен в простую основную функцию (я определил вручную входной файл `char fileLine [] =" q, d, c, k "):

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

int main(void)
{
  char *initialParts, *token;
  char fileLine[] = "q,d,c,k";
  const char comma[3] = ",";
  int initialPartsCounter = 0, numInitialParts = 20;
  initialParts = (char*)malloc((int)numInitialParts * sizeof(char));

  token = strtok(fileLine, comma);

  while (token != NULL)
  {
    //strcpy(&initialParts[initialPartsCounter], token);
    initialParts[initialPartsCounter] = *token; //Use this only if tokens are only one char long
    initialPartsCounter++;
    token = strtok(NULL, comma);
  }

  for (int l = 0 ; l < initialPartsCounter; l++)
  {
    printf("%c", initialParts[l]);
  }
  printf("*end\n");

  free(initialParts);

  return 0;
}

Я также напечатал закрывающую строку , чтобы показать, что в ней нет завершающего неожиданного символа. Выход

qdck*end
0 голосов
/ 01 мая 2020
initialParts = (char*)malloc((int)numInitialParts * sizeof(char));

Вы должны использовать двойной указатель или двумерный массив для хранения token (потому что это последовательность символов (строка), а не символ). Если вы не знаете, сколько деталей раньше, вы можете использовать realloc каждый раз, когда увеличиваете numInitialParts

Например:

char **initialParts = malloc(sizeof(char*));

// check initialParts here

token = strtok(fileLine, comma);

while (token != NULL) {
    initialParts[initialPartsCounter] = malloc(sizeof(char) * 2);
    // check initialParts[initialPartsCounter] here
    strcpy(initialParts[initialPartsCounter], token);
    initialPartsCounter++;
    initialParts = realloc((initialPartsCounter+1)*sizeof(char));
    // check initialParts here
    token = strtok(NULL, comma);
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...