strcpyの...はstrncpyとヌル終了しますstrcpy_mineと交換したいです
質問
手がかりはタイトルにあるが、基本的に私はstrcpyのの800+のインスタンスを持っているいくつかのコードを継承しました。私は、新しい関数を記述し、その後strcpy_mineでのstrcpyを交換したいです。
だから私は、パラメータリストstrcpy_mineがありますどのような動作するようにしようとしています。
私が試します:
void strcpy_mine( char* pTarget, const char* const pCopyMe )
{
const unsigned int lenAlwaysFour = sizeof(pCopyMe ); //:(
strncpy( pTarget, pCopyMe, lenAlwaysFour );
//add extra terminator in case of overrun
pTarget[lenAlwaysFour] = 0;
}
が、のsizeofは4 pCopyMeあるポインタ
常に私は何をしたくないこと置き換えるです。
strcpy (buf, pCopyMe);
タグ付き
strncpy (buf, pCopyMe, sizeof(pCopyMe)); buf[sizeof(pCopyMe)] = 0;
任意のアイデア? (strcpy_lが利用できない)
歓声
解決
例が多い大半は単純なテンプレートで扱うことができ、同様に呼び出しサイトがどのように見えるかに応じて、
#include <string.h>
template <int bufferSize>
void strcpy_mine( char (&pTarget)[bufferSize], const char* const pCopyMe )
{
strncpy( pTarget, pCopyMe, bufferSize-1 );
//add extra terminator in case of overrun
pTarget[bufferSize-1] = 0;
}
int main()
{
char buf[128];
strcpy_mine(buf,"Testing");
return 0;
}
あなたは、Microsoft Visual Studio 2005またはそれ以降を使用している場合は、参照<のhref = "http://msdn.microsoft.com/en-us/library/ms175759(VS.80).aspx" のrel = "nofollowをnoreferrer 「>マイクロソフトの実装のためのテンプレートオーバーロードに固定します。
他のヒント
はsizeof()タイプのサイズを返し - 32ビットマシン上で4になり、この場合のconst char* const
に
私はあなたがstrlen()
をしたいと思うと思います。しかし、それははstrncpy関数を使用する正しい方法ではありません。
あなたはstrncpyをのための出力のバッファのサイズを必要とします。
あなたは各呼び出しサイトでコードを調べると、出力バッファのサイズをうまく、そしてstrcpy_mine
の引数としてそれを渡す必要があり、この問題を解決するには。呼び出しサイトのstrcpy(またはstrcpy_mine)のためには、出力バッファのサイズを知らない場合は、バッファを割り当てる場所のコード内で後方検索、およびすべての方法ダウンstrcpyのサイトにサイズを渡す必要がありますます。
基本的には同じ引数を取りstrcpyのための代替の低下を書いて、最初の場所(とそれを超え、より良い代替品)にはstrncpyを生成する問題を回避することを望むことはできません。あなたはstrncpyを同じ引数を取りますが、結果はnull終端で確実に機能を作成することができます - <のhref =「http://en.wikipedia.org/wiki/Strlcpy」のrel = "nofollowをの実装を見てnoreferrer "> OpenBSDのstrlcpyに()の機能。しかし、最初のステップは、出力バッファサイズの知識を渡すために呼び出しサイトを変更するにする必要があります。
少し周辺おそらく、しかし、誰もがそれを言及し、タイトルに誇示していますので、:。あなたが(合法的に)strcpy_mine()
というグローバル関数を記述することはできません。
名前str
で始まる関数の「名前空間が」標準ライブラリ用に予約されています。例えば、、参照してください。質問するます。
あなたはstrcpy_mineのためのstrncpyと同じパラメータリストを使用しますが、それは常にnull結果を終了するようにそれを書くことができます。やることは非常に難しいことではありません。
1つの課題は、しかし、(strcpyのを呼び出す既存のコードの一部が)のいずれか、バッファのサイズを知らないかもしれないことを。
でありますまた、あなたは避け、複数のeditingsためmacrosesを使用することができます。あるいは、いくつかのスクリプトを経由して編集を自動化します。
あなたは間違いなく、他の人が上記述べたように、パラメータとして宛先バッファのサイズに渡す必要があります。
これは一種のオフトピックですが、私はちょうどあなたがstrncpy()
を使用した後、あなたはインデックスの1以下を持っているバッファの最後の文字を、nullに設定する必要がある、ということを指摘したいです長さ(バッファのない長さ)よりも
strncpy (buf, pCopyMe, buflen); buf[buflen - 1] = '\0';
または代わりに、あなたはそれを1以下の長さを渡して、空の文字列にstrncat()
を使用することができ、そしてそれはあなたの文字列をNULLで終了することを保証します。
buf[0] = '\0'; strncat (buf, pCopyMe, buflen - 1);
ダグラスLeederはそれが権利を有します。あなたは一人ひとりのインスタンスでの良い、まともなバッファ長を渡すの面倒な作業をしても構わないと思っていない限りのstrcpyを置き換えるの有用性には限界があります。それは多くの作業だ!
良いニュースは、それは価値がある、あります!戻る数年前、私はいくつかのC ++遅れたプロジェクト、バギー、および信頼性に欠ける上で来ました。禁断のstrcpyとstrlenのを宣言し、私たちは突然日間の代わりに、時間のために実行可能性があり、これらすべてのプロジェクトでは、strnlenカスタムはstrncpy /でそれらを置き換えるためにプロジェクトのうち、2〜3日を取ること。また、切り捨てられた文字列の多くは、画面表示に出てくるとログファイルを見ました。これは、以前の問題をクラッシュ、私たちに切り捨ての問題を追跡するために必要な手がかりを与えます。
あなたがこれを行うにはしたくない場合は、は、あなたが単にNULLのため、両方のポインタパラメータをチェックして、文字列コピーの最大サイズを制限するとのすべての回をロギング境界に到達したことにより、はるかに小さい利益を得ることができます。 の、いずれかのパラメータのstrlen関数をしないでください文字列が正しくない場合は喜んであなたにクラッシュするstrlenをnullとして終了します。
今日では、新しいプロジェクトが良い文字列オブジェクトを使用しますが、レガシーコードの多くはそうではないことそこにあります。