Как я могу сделать строки содержащие разделитель после токенизации? - PullRequest
1 голос
/ 18 апреля 2019

Я только начал изучать язык Си в Ubuntu, я пытался создать простую оболочку, которая немного работает как оболочка.Итак, сразу после того, как я получу командную строку, я думаю, что, возможно, мне придется разделить строку с разделителем.во-первых, я хочу токенизировать строку с разделителем '&', содержащим разделитель, используя "strtok_r ()", но "strcat ()" почему-то не работает через то, что я хотел

я пытался использовать "strcat ()"после изготовления жетонов.если я использую функцию, вывод первого токена хорошо работает со вторыми токенами, однако, выбрасывается.

вывод просто так.Допустим, у меня есть эти токены.

token1 : abcde
token2 : fghij

, а затем, если я использую "strcat ('&')" с этим, его результат будет выглядеть как

token1 : abcde&
token2 : &

Я думаю, что это можетбыть потому что разделитель, который я пытаюсь поставить в конце "token1" влияет на адрес для "token2".

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

int main()
{
        static const char delim[] = "&";

        char str[256] = "sleep 5 & echo Hello & sleep 5; echo Hello";

        char *args[50];

        char *save;
        char *pBuf;
        int i = 0;

        for(pBuf = strtok_r(str, delim, &save);
                        pBuf;
                        pBuf = strtok_r(NULL, delim, &save)){

                printf("%d\n", i);
                args[i++] = pBuf;

        }


        /** OUT PUT START*/

        i = 0;

        while(args[i]){
                printf("args[%d] : %s\n", i , args[i]);
                i++;
        }

        /**OUT PUT END  */

        return 0;
}


********OUT PUT

args[0] : sleep 5
args[1] :  echo Hello
args[2] :  sleep 5; echo Hello

********EXPECTED OUT PUT

args[0] : sleep 5 &
args[1] : echo Hello &
args[2] : sleep 5; echo Hello 

1 Ответ

1 голос
/ 18 апреля 2019

Вопрос в том, что хорошего strtok делает в этом случае.Вместо того, чтобы усложнять процесс, вы можете просто выполнить синтаксический анализ вручную с помощью strchr.Как только вы найдете разделитель &, вы можете ожидать завершающий пробел и напечатать этот пробел и конец, а не начало.Пример:

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

int main(void)
{
  const char str[256] = "sleep 5 & echo Hello & sleep 5; echo Hello";
  size_t length = strlen(str);

  const char* s1 = str;
  const char* s2;
  const char delim = '&';

  while(s1 < str+length)
  {
    s2 = strchr(s1, delim);
    if(s2 == NULL)
    {
      s2 = &str[length]; // point at null term
    }
    else
    {
      s2++; // point at space
    }
    printf("%.*s\n", s2-s1, s1); // print (s2-s1) characters
    s1 = s2+1; // point at next char after space, or 1 past null term
  }
}

Вывод:

sleep 5 &
echo Hello &
sleep 5; echo Hello

(Обратите внимание, что в C вполне нормально указывать 1 элемент после конца массива, но не отменять ссылки на этот адрес.) * +1010 *

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