如何在C中删除String的子字符串

时间:2018-05-23 19:19:31

标签: c

我很难在C中获取字符串的子字符串。例如,如果我有

char *buff = "cat –v <  x y z | ";
char *p = strtok (buff, " ");
while (p != NULL)
{
    if (!strcmp(p, "<") && !isredirected)
    {
        isredirected = 1;
        infileindex  = tokenscounter + 1;
        inputredirectionindex = tokenscounter;
    }
    commandsArray[tokenscounter++]  = p;
    p = strtok (NULL, " ");

}

来自此buff字符串,我想删除&#39;&lt;&#39; &#39; |&#39; 。即删除x y z。我使用strtok来解析所有标记,但无法删除x y z。找到&#39;&lt;&#39; 后,我想摆脱&lt; 之后和 |

2 个答案:

答案 0 :(得分:0)

(几乎)没有内置解决方案:

  • 您要修改 inplace :在这种情况下,您必须&#34;移动&#34;字符串的结尾(基本上是|);
  • 或创建一个新字符串,复制相关部分,跳过不是。

答案 1 :(得分:0)

另一种选择是一个简单的函数,它迭代源字符串,将不要删除的字符复制到目标字符串,如下所示。

char *  CopyStringRemove(char *pDest, const char *pSrc)
{
    // copy the source string, pSrc, to the destination string, pDest, while
    // removing special codes that are between a < character and a | character.
    // we will copy the two special code characters but remove everything in between.
    char * pRet = pDest;

    if (pDest) {
        if (pSrc) {
            int   iState = 0;      // state indicates whether copying characters or not.

            for (; *pSrc; pSrc++) {
                switch (*pSrc) {
                case '<':
                    iState = 1;         // indicate we are skipping characters
                    *pDest++ = *pSrc;   // however copy this character we found
                    break;
                case '|':
                    iState = 0;     // indicate we are copying characters
                    break;
                default:
                    break;
                }
                switch (iState) {
                case 0:
                    *pDest++ = *pSrc;    // state is to copy the current character
                    break;
                case 1:                  // state is to not copy current character, just skip over it.
                    break;
                }
            }
        }
        *pDest = 0;
    }

    return pRet;
}

此函数提供了相当大的灵活性,因为源可以是常量或不是常量。目标可以是堆栈上的数组或从堆中malloced的数组。如果源数组不是const,则可以通过调用CopyStringRemove()函数进行就地更改,同时源和目标都是相同的缓冲区。

它还允许输入问题,例如没有&#39;&#39;字符或&#39; |&#39;字符串中的字符。

测试工具如:

void testfunc(const char *buff)
{
    {
        char destbuff[128] = { 0 };
        printf("    orig string \"%s\"\n", buff);
        CopyStringRemove(destbuff, buff);
        printf("        new     \"%s\"\n", destbuff);
    }

    {
        char destbuff[128] = { 0 };
        char buff2[128] = { 0 };
        strcpy_s(buff2, sizeof(buff2), buff);
        printf("    orig string \"%s\"\n", buff2);
        CopyStringRemove(destbuff, buff2);
        printf("        new     \"%s\"\n", destbuff);
    }

    {
        char buff2[128] = { 0 };
        strcpy_s(buff2, sizeof(buff2), buff);
        printf("    orig string \"%s\"\n", buff2);
        CopyStringRemove(buff2, buff2);
        printf("        new     \"%s\"\n", buff2);
    }

}

void main_xfun(void)
{
    char *buff = "cat -v <  x y z | ";
    char *buffa = "cat -v <  x y z  ";
    char *buffb = "cat -v   x y z | ";
    char *buffc = "cat -v   x y z  ";

    printf("\ntest #1\n");
    testfunc(buff);
    printf("\ntest #2\n");
    testfunc(buffa);
    printf("\ntest #3\n");
    testfunc(buffb);
    printf("\ntest #4\n");
    testfunc(buffc);
}

产生以下结果:

test #1
    orig string "cat -v <  x y z | "
        new     "cat -v <| "
    orig string "cat -v <  x y z | "
        new     "cat -v <| "
    orig string "cat -v <  x y z | "
        new     "cat -v <| "

test #2
    orig string "cat -v <  x y z  "
        new     "cat -v <"
    orig string "cat -v <  x y z  "
        new     "cat -v <"
    orig string "cat -v <  x y z  "
        new     "cat -v <"

test #3
    orig string "cat -v   x y z | "
        new     "cat -v   x y z | "
    orig string "cat -v   x y z | "
        new     "cat -v   x y z | "
    orig string "cat -v   x y z | "
        new     "cat -v   x y z | "

test #4
    orig string "cat -v   x y z  "
        new     "cat -v   x y z  "
    orig string "cat -v   x y z  "
        new     "cat -v   x y z  "
    orig string "cat -v   x y z  "
        new     "cat -v   x y z  "