文字列をコピーする方法とトラップ

序文

実際のプロジェクトの開発では、文字列のコピーは非常に一般的な使い方です。何か問題が一般的に発生しない、またはコンパイラがエラーをコンパイルし、あるいはエラーを実行していない一般的である多くの方法は、我々が使用する、あります。しかし、いくつかの潜在的な落とし穴は、VS 2017の開発を使用して、あなたはより厳格になり、検出文法コンパイラの多くを見つけるときのように、しばしば存在している、以前にこのようVS2010与えられていない、vs2017はコンパイル、または成功し、実行エラーがコンパイルされません。

ナンセンスは:ちょうど仕事をする時に、私は機能を実現することができる限り感じ、タスクを完了することです。経験で、多くのことをそんなに使わなぜ利益何、効率が高くなることはないだろうとので、パフォーマンスは良くなりません、と思うし、一番下に到達するために行くのが好き。

まあ、ナンセンスは、今日のディスカッショントピックの公式オープニング以下、単に言葉以上のものです。

コピーフォーマット

多くの文字列は、道をコピーし、ここで私は主にmemcpyを、strcpyのは、これら3つの文字列::コピーについて話があります。

メモリコピーmemcpyを

関数原型

    void* __cdecl memcpy(
    _Out_writes_bytes_all_(_Size) void* _Dst,
    _In_reads_bytes_(_Size)       void const* _Src,
    _In_                          size_t      _Size
    );

シンプルなポイント:

void *memcpy(void *dest, const void *src, size_t count);

パラメータは、ここでは詳しく説明しません。

例:

std::string CopyString(const std::string &strBody)
{
    int nLen = strBody.length();
    char *cBody = new char(nLen);
    memcpy(cBody, strBody.c_str(), nLen);
    std::cout << "FONCTION:" << cBody << std::endl;
    return cBody;
}

int main()
{
    std::string strBody = "This is a Test!";
    std::string strReturn = CopyString(strBody);
    std::cout << "MAIN:" << strReturn.c_str() << std::endl;
    system("pause");
    return 0;
}

上記の関数は、エラーは、ほとんどの場合には発生しませんが、潜在的なトラップがあります。

トラップ

文字列の最後のメモリコピーはありません'\0'チェックします

結果

コピーした後、文字列の末尾に文字化け。

ソリューション

ストリングの端部が内にコピーすることを確実にするために、メモリのためのメモリのマルチバイトを適用する場合。

std::string CopyString(const std::string &strBody)
{
    int nLen = strBody.length();
    char *cBody = new char(nLen + 1);
    memcpy(cBody, strBody.c_str(), nLen + 1);
    std::cout << "FONCTION:" << cBody << std::endl;
    return cBody;
}

int main()
{
    std::string strBody = "This is a Test!";
    std::string strReturn = CopyString(strBody);
    std::cout << "MAIN:" << strReturn.c_str() << std::endl;
    delete strReturn.c_str();
    system("pause");
    return 0;
}

コピー文字列にstrcpy

関数原型

char* __cdecl strcpy(
    _Out_writes_z_(_String_length_(_Source) + 1) char*       _Dest,
    _In_z_                                       char const* _Source
    );

シンプルなポイント:

char *strcpy(char *dst, const char *src);

std::string CopyString(const std::string &strBody)
{
    int nLen = strBody.length();
    char *cBody = new char(nLen);
    strcpy(cBody, strBody.c_str());
    std::cout << "FONCTION:" << cBody << std::endl;
    return cBody;
}

int main()
{
    std::string strBody = "This is a Test!";
    std::string strReturn = CopyString(strBody);
    std::cout << "MAIN:" << strReturn.c_str() << std::endl;
    delete strReturn.c_str();
    system("pause");
    return 0;
}

説明

strcpy文字列のコピー機能に特化し、そしてmemcpy違いは、文字の終わりを検出することで'\0'アプリケーションのメモリが過剰適用されないように、。

コピー文字列stringの方法::コピー

プロトタイプ

    size_type copy(_Out_writes_(_Count) _Elem * const _Ptr,
        size_type _Count, const size_type _Off = 0) const
        {   // copy [_Off, _Off + _Count) to [_Ptr, _Ptr + _Count)
        auto& _My_data = this->_Get_data();
        _My_data._Check_offset(_Off);
        _Count = _My_data._Clamp_suffix_size(_Off, _Count);
        _Traits::copy(_Ptr, _My_data._Myptr() + _Off, _Count);
        return (_Count);
        }

それとも単純なポイント:

size_t copy (char* s, size_t len, size_t pos = 0) const;

ここでは、これらのパラメータを説明する:
Sの
ポインタを文字のセットに。
この配列には、文字をコピーするための十分な収納スペースが含まれている必要があります。
LENの
文字の数は、(文字列が短い場合は、できるだけ多くの文字がコピーされている)コピーします。
posに
コピーする最初の文字の位置を。
これは、文字列の長さよりも大きい場合、それはout_of_rangeをスローします。
注:最初の文字列が0の値(ない1)で表されます。

// string::copy
#include <iostream>
#include <string>

int main ()
{
  char buffer[20];
  std::string str ("This is a Test");
  std::size_t length = str.copy(buffer,6,5);
  std::cout << "buffer contains: " << buffer << '\n';
  return 0;
}

トラップ&結果

こののでcopy機能はまだ最後の呼び出しであるmemcopyため、同じトラップ、コピーが完了した後、それはちんぷんかんぷんの文字列の束を取り戻すだろう

ソリューション

コピー、プラスターミネーターの終わりに'\0'

// string::copy
#include <iostream>
#include <string>

int main ()
{
  char buffer[20];
  std::string str ("This is a Test");
  std::size_t length = str.copy(buffer,6,5);
  buffer[length]='\0';
  std::cout << "buffer contains: " << buffer << '\n';
  return 0;
}

私の現在の結果が正確であるのでここでは、そこの方法ですが、このアプローチが議論されます。これは、適用後にメモリに初期化するのは初めてなので、文字化けコピーが表示されません。
例えば:

std::string CopyString(const std::string &strBody)
{
    char *cBody = NULL;
    int nLen = strBody.size();
    cBody = (char *)malloc(nLen);
    memset(cBody, 0, nLen);
    strBody.copy(cBody, nLen, 0);
    std::cout << "FONCTION:" << cBody << std::endl;
    return cBody;
}

int main()
{
    std::string strBody = "This is a Test!";
    std::string strReturn = CopyString(strBody);
    std::cout << "MAIN:" << strReturn.c_str() << std::endl;
    system("pause");
    return 0;
}

後書き

当社の開発プロセスでは、詳細の多くは、我々は問題が、問題に触れないよう、細部に、精査に注意が必要で、でも問題は、特に大規模なプロジェクトでは、見つけるのは簡単です。

おすすめ

転載: blog.csdn.net/weixin_34411563/article/details/90970575