序文
実際のプロジェクトの開発では、文字列のコピーは非常に一般的な使い方です。何か問題が一般的に発生しない、またはコンパイラがエラーをコンパイルし、あるいはエラーを実行していない一般的である多くの方法は、我々が使用する、あります。しかし、いくつかの潜在的な落とし穴は、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;
}
後書き
当社の開発プロセスでは、詳細の多くは、我々は問題が、問題に触れないよう、細部に、精査に注意が必要で、でも問題は、特に大規模なプロジェクトでは、見つけるのは簡単です。