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

に関してsizeof(cleaned)sizeof配列の容量を取得するために使用することは、引数がポインタではなく配列である場合にのみ機能します。

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));

ローカル配列とポインタの両方に添え字を付けることができますが、。に関しては動作が異なりsizeofます。したがって、配列へのポインタのみが与えられた場合、配列の容量を決定することはできません。

また、これを覚えておいてください:

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++;
}

は配列のように宣言されていnot_really_an_arrayますが、これは関数パラメーターであるため、実際にはポインターです。これは、次とまったく同じです。

void foo(char *not_really_an_array)
{
...

あまり論理的ではありませんが、私たちはそれに固執しています。


あなたの質問に移りましょう。あなたが何をしようとしているのかわかりません。文字列の最初の文字を(インプレースで)削除するだけで、memmoveを使用して実行できます。

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

これには線形時間がかかりbuffer、空の文字列が含まれていないことを前提としています。

strcpy(buffer, buffer + 1)文字列がオーバーラップするため、これが行われない 理由は、未定義の動作をもたらすためです。memmoveただし、送信元と宛先を明示的にオーバーラップさせることができます。

より複雑な文字フィルタリングについては、「読み取り」ポインターと「書き込み」ポインターを使用して、文字列を手動でトラバースすることを検討する必要があります。書き込みポインタが読み取りポインタよりも先に進まないように注意してください。そうすれば、文字列が読み取られている間に文字列が壊れることがありません。

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

3文字のシーケンス(コンマスペースのセミコロン)を検索してから、最初の2文字(コンマとスペース)を削除します。セミコロンも削除する場合は、3文字すべてを削除する必要があります(toRemove+3の代わりに使用してくださいtoRemove+2)。また、文字列を終了するNULバイトを考慮して、strlenの結果に1を追加する必要があります。

あなたが言うように、最初のセミコロンだけを削除したい場合は、セミコロンだけを検索する必要があります(これはで行うことができます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 に答える