0

正しい場所にコピーしますが、カウントに達しても停止しません。私のコードは次のように動作するはずだと思いました

char har *orig, int start, int count, char *final);

int main(void)
{
    const char source[] = "one two three";
    char result[] = "123456789012345678";

    printf("%s\n",GetSubstring(source, 4, 3, result));

    return 0;
}

char r *orig, int start, int count, char *final)
{    
    char *temp = (char *)orig;

    final = temp;


   }

    for ( ; *temp && (count > 0) ; count--)
    {
    rn final;
}
4

6 に答える 6

3
  1. 最初のforループは、配列が存在するかどうかをチェックしませんtemp(何らかの方法でメモリ マネージャーに問い合わせずに、割り当てられたメモリの存在をチェックするにはどうすればよいでしょうか?!)。はtemp単なるポインタです。チェックしているのは、文字列の最初のバイトorigにゼロがないことです。start大丈夫、たぶん」それがあなたの「存在」の意味です。

  2. あなたの意図は から にコピーするorigことfinalですが、 にリセットfinalorigます。それがあなたのエラーです。その行を削除する必要があり、問題が修正されます。

  3. ポインターを作成する必要はありません。ポインターtempを使用できorigます。自由に変更できます。覚えておいてください、関数の引数は効果のあるローカル変数です。C の関数引数は値渡しです。データへのポインター (値です!) を渡すことで参照渡しを実装します。

おそらく、この関数の前提がいくぶん壊れていることを付け加えておく必要があります。それは「機能します」が、合理的に期待できるものではありません。特に:

  1. ソース文字列が より短いという兆候はありませんstart

  2. ソース文字列が より短いという兆候はありませんstart + count

    おそらくそれらは問題ありませんが、それらの条件がエラーである可能性がある場合、関数のユーザーがそれを示すことができるはずです。発信者は何が期待され、何が期待されていないかを知っているため、発信者にフィードバックを提供するだけで、発信者はそれを判断できます。

  3. 出力の終わりを1つ過ぎた位置、つまりゼロ終端を過ぎた位置を返しています。それはあまり便利ではありません。返された値を使用して後続の文字列を連結する場合は、最初に 1 つ減らす必要があります。

以下は、適切な名前の変数を使用した修正コードです。

char *GetSub(const char *src, int start, int count, char *dst)
{
    for ( ; *src && (start > 0) ; start--)
    {
        src++; /* Note: *src++ works too, but is pointless */
    }

    for ( ; *src && (count > 0) ; count--)
    {
        *dst++ = *src++;
    }

    *dst++ = 0;
    return dst; /* Notice: This returns a pointer to the end of the
                memory block you just wrote. Is this intentional? */
}
于 2012-07-31T12:43:04.293 に答える
1

あなたの書いたものにはいくつかの問題があります。列挙しましょう:

  1. char *temp = (char *)orig;const char *- (変更しないことを約束する) をchar *(約束を破る) に割り当てています。間違ったことをしている。

  2. final = temp. いいえ、これはオリジナル final(発信者が保持するコピー) をまったく変更しません。それは何も達成しません。あなたの(関数の)コピーがfinal、指しているのと同じ場所を指すように変更しますtemp

  3. *temp++;- 使用しない場合は、逆参照しても意味がありません。もちろん、それを増やすことは正しいです[以下のKubaOberのコメントスレッドを参照してください]。

  4. final++ = *temp++;- これは読みにくいです。

  5. *final++ = 0; return final;- アドレスの値finalを「0」に設定しています。次に、それをインクリメントします(宇宙のどこか、おそらくブラックホールに向かって)。次に、そのポインタを返します。これも間違っています。

本当にすべきことは、便利な方法でラップすることです。strncpy

しかし、どうしても自分で書きたい場合は、関数を次のように単純なものにしたいと思うでしょう。

char *GetSub(const char *orig, int start, int count, char *final)
{    
  int i;

  for (i = 0; i < count; i++)
    {
      final[i] = orig[i+start];

      if (final[i] == '\0')
        break;
    }
  final[i] = '\0';

  return final; /* Yes, we just return what we got.  */
}
于 2012-07-31T12:36:05.870 に答える
1

問題は次の行にあります。

final = temp;

それを削除すると、問題は解決するはずです。

于 2012-07-31T12:44:28.140 に答える
0
char *a="abcdefgh";

文字列「cde」を別の文字列にコピーしたい。

私が得たインデックスは3(あなたのスタート)です。

char *temp=malloc(3*sizeof(char))
strncpy(temp,a+3,3);

これはあなたが必要とするものですか?

于 2012-07-31T12:29:25.293 に答える
0

GetSub関数を変更します。

char *GetSub(const char *orig, int start, int count, char *final)
{
    char *temp = (char *)orig;

    // with original final = temp and final++ you loose final valid pointer
    char *final2 = final;


    for ( ; *temp && (start > 0) ; )
    {
        start--;

        // you don't need to dereference temp
        temp++;
    }

    for ( ; *temp && (count > 0) ; count--)
    {
        *final2++ = *temp++;
    }

    *final2 = 0;

    // return a valid pointer
    return final;
}
于 2012-07-31T12:44:35.550 に答える
-2

コードにいくつかの間違いがあります:

char *GetSub(const char *orig, int start, int count, char *final)
{
    char *temp = (char *)orig;

    //final = temp; /* Why this? */

    for ( ; *temp && (start > 0) ; )
    {
        start--;
        temp++; /* Instead of *temp++ */
    }

    for ( ; *temp && (count > 0) ; count--)
    {
        *final++ = *temp++;
    }

    *(final+count) = '\0';
    return final;
}

この助けを願っています。

于 2012-07-31T12:44:05.973 に答える