0

我试图从一个字符数组中删除第一个分号,其值为:

输入:
; 测试:876033074、808989746、825766962、;测试1:825766962,

代码:

 char *cleaned = cleanResult(result);
            printf("Returned BY CLEAN: %s\n",cleaned);



    char *cleanResult(char *in)
    {   
        printf("Cleaning this: %s\n",in);

        char *firstOccur = strchr(in,';');
        printf("CLEAN To Remove: %s\n",firstOccur);
        char *restOfArray = firstOccur + 2;
        printf("CLEAN To Remove: %s\n",restOfArray); //Correct Value Printed here

        char *toRemove;
        while ((toRemove = strstr(restOfArray + 2,", ;"))!=NULL) 
        {
            printf("To Remove: %s\n",toRemove);
            memmove (toRemove, toRemove + 2, strlen(toRemove + 2));
            printf("Removed: %s\n",toRemove); //Correct Value Printed
        }

        return in;
    }

输出(第一个分号仍然存在)
:; 测试:876033074、808989746、825766962;测试1:825766962;

4

3 回答 3

4

Regarding sizeof(cleaned): using sizeof to get the capacity of an array only works if the argument is an array, not a pointer:

char buffer[100];
const char *pointer = "something something dark side";

// Prints 100
printf("%zu\n", sizeof(buffer));

// Prints size of pointer itself, usually 4 or 8
printf("%zu\n", sizeof(pointer));

Although both a local array and a pointer can be subscripted, they behave differently when it comes to sizeof. Thus, you cannot determine the capacity of an array given only a pointer to it.

Also, bear this in mind:

void foo(char not_really_an_array[100])
{
    // Prints size of pointer!
    printf("%zu\n", sizeof(not_really_an_array));

    // Compiles, since not_really_an_array is a regular pointer
    not_really_an_array++;
}

Although not_really_an_array is declared like an array, it is a function parameter, so is actually a pointer. It is exactly the same as:

void foo(char *not_really_an_array)
{
...

Not really logical, but we're stuck with it.


On to your question. I'm unclear on what you're trying to do. Simply removing the first character of a string (in-place) can be accomplished with a memmove:

memmove( buffer             // destination
       , buffer + 1         // source
       , strlen(buffer) - 1 // number of bytes to copy
       );

This takes linear time, and assumes buffer does not contain an empty string.

The reason strcpy(buffer, buffer + 1) won't do is because the strings overlap, so this yields undefined behavior. memmove, however, explicitly allows the source and destination to overlap.

For more complex character filtering, you should consider traversing the string manually, using a "read" pointer and a "write" pointer. Just make sure the write pointer does not get ahead of the read pointer, so the string won't be clobbered while it is read.

void remove_semicolons(char *buffer)
{
    const char  *r = buffer;
    char        *w = buffer;

    for (; *r != '\0'; r++)
    {
        if (*r != ';')
            *w++ = *r;
    }

    *w = 0; // Terminate the string at its new length
}
于 2011-12-07T21:47:46.583 回答
3

您正在使用带有重叠输入/输出缓冲区的 strcpy,这会导致未定义的行为。

于 2011-12-07T21:29:14.200 回答
-1

您正在搜索三个字符的序列(逗号空格分号),然后删除前两个字符(逗号和空格)。如果您也想删除分号,则需要删除所有三个字符(使用toRemove+3代替toRemove+2)。您还需要将 1 添加到 strlen 结果以说明终止字符串的 NUL 字节。

如果,正如您所说,您只想删除第一个分号而不需要其他任何内容,则只需搜索分号(您可以使用strchr):

if ((toRemove = strchr(in, ';'))    // find a semicolon
    memmove(toRemove, toRemove+1, strlen(toRemove+1)+1);  // remove 1 char at that position
于 2011-12-07T23:06:19.020 回答