VS2005 + XPで開発しています。
VS2005に環境を変更したのですが、
strcpy_sなどのサイズの指定の方法に困っています。
たとえば、以下のソースで
関数に渡した先でサイズを取得することはできるのでしょうか?
関数に文字列を渡す際にサイズも一緒に渡す必要があるのでしょうか?
分かる方がいましたら、教えてください。
よろしくお願いします。
int main()
{
char c[50];
test(c);
}
void test(char *c)
{
char str[50];
// ここでXXXに[c]のサイズを指定したい
strcpy_s(str,XXX,c);
}
すいません。例えのソースを間違いました。
こんな感じのことをしたいのです。
int main()
{
char c[50];
test(c);
}
void test(char *c)
{
char str[50] = "test";
// ここでXXXに[c]のサイズを指定したい
strcpy_s(c,XXX,str);
}
C言語では"ポインタ"変数にしてしまった状態で配列のサイズを取得する方法はありません。
test関数の引数に配列のサイズも渡すようにしてください。
追記するなら、
strcpy_sと言う関数にサイズが付けられたのは、
正に同じ理由でポインタで引き渡された先のサイズを取得する方法が無い為、
チェックしようにもチェックできないからです。
但し、同じ理由で引き渡したサイズがバッファのサイズを正しく示していない
場合は、せっかくのstrcpy_sも期待した効果は出ないと思います。
keichanさんが書かれている通り、test関数自体にサイズを引き渡す為の
引数を追加してそれを使うしかないと思います。
どちらにしても正確なサイズが引き渡されなければ、効果は期待できないのですけれど。
keichanさん、返信ありがとうございます。
>C言語では"ポインタ"変数にしてしまった状態で配列のサイズを取得する方法はありません。
やっぱりそうですか・・・
関数にサイズを渡すようにします。
ありがとうございました。
PATIOさん、返信ありがとうございます。
>strcpy_sと言う関数にサイズが付けられたのは、
>正に同じ理由でポインタで引き渡された先のサイズを取得する方法が無い為、
>チェックしようにもチェックできないからです。
こんな理由があったんですね、
くわしい情報ありがとうございます。
strcpy_sのようにtemplateを使って配列として渡せば可能なんじゃないかな。
(現在試すことは出来ないけど)
>void test(char *c)
↓
template <size_t size>
void test(
char (&c)[size],
) // C++ only
{
・・・・
類似スレ
http://f4.aaa.livedoor.jp/~pointc/No.25075.html
VS2005でソース内をgrepしたんですが、
strcpy_sにこの記述は見つかりませんでした。
template <typename _CharType>
inline
errno_t _tcscpy_s(
__out_ecount_z(_Size) _CharType *_Dest,
__in size_t _Size,
__in_z const _CharType *_Src
)
{
と言うのは見つかったんですけれど。
template <typename _CharType>っていうのは普通にやりますし、
どの辺に載っていたのか知りたいのでぜひ教えてください。
>VS2005でソース内をgrepしたんですが、
>strcpy_sにこの記述は見つかりませんでした。
実は私も、ソースまでは見ていません。
MSDNでstrcpy_sを調べたら、宣言がhttp://f4.aaa.livedoor.jp/~pointc/No.25075.htmlに載せたように
なっていたので、試してみたら使えた記憶があります。
[MSDN]strcpy_s、wcscpy_s、_mbscpy_s
http://msdn2.microsoft.com/ja-jp/library/td1esda9(VS.80).aspx
strcpy_sを選択して、右クリックメニューの「定義位置へ移動」をつかうと
string.hの72行目に
__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, strcpy_s, __out_ecount_z(_Size) char, _Dest, __in_z const char *, _Source)
であることがわかります。
同様にして、それぞれのマクロの定義を確認することができます。
マクロ展開の結果がこうなるわけですね。
了解です。
Blueさん、返信ありがとうございます。
>template <size_t size>
>void test(
> char (&c)[size],
>) // C++ only
>{
template、使ったことありません・・・
よく使われるものなんでしょうか?
template調べてみます。
いつの間にか、何か難しい話になってますね。
>template、使ったことありません・・・
templateは完全に C++ の話になってしまいます。
まぁ、VC++2005ってことで一応ありかなと。
>よく使われるものなんでしょうか?
リストのようなコンテナクラスではよく使いますね。
(STLならstd::vectorとかstd::listとか、MFCならCArrayとかCListとか)
>template調べてみます。
C++の入門書ならどれも載っているのかな。
Google等で検索してみても、参考になるサイトはたくさん見つかると思います。
Blueさん、返信ありがとうございます。
手元にC++の入門書もネット環境もありますので、
色々と調べてみようと思います。
void test( char (*arg)[50] )
{
size_t arg_size = sizeof(*arg) / sizeof(*arg[0]);
strcpy_s( *arg, arg_size, "test" );
}
int main()
{
char c[50];
test( &c );
return 0;
}
じゃだめなんですかね?
配列の要素数を渡したくないけど、
渡さなきゃだめですか?って質問だった orz
↑のは引数に配列の数思いっきり書いてるから
質問者の意図からはずれてますね。
申し訳ないm(_ _)m
>size_t arg_size = sizeof(*arg) / sizeof(*arg[0]);
これって意味があるのでしょうか?
>void test( char (*arg)[50] )
50とここで固定にしているから、arg_sizeは50なのは決まっているのでは
ないのでしょうか?
手元にVS2005環境がないので間違ったこと抜かしているかもしれませんけど。。。
> これって意味があるのでしょうか?
意味はないですね。
50って限定してますし。
一応(配列の)ポインタ渡して配列の数が取れるよって
例を上げてみたんですが、そもそも質問の意図からはずれてますし。。。
>> これって意味があるのでしょうか?
> 意味はないですね。
強いて言えば
void test( char (*arg)[100] )
に変わったときにstrcpy_sのほうを書き換えなくて済むってことくらいですね。
ツイート | ![]() |