VS2005でstrcpy_sなどのサイズを指定するには?

解決


メルティー  2006-12-05 01:11:54  No: 63809

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);
}


メルティー  2006-12-05 01:15:43  No: 63810

すいません。例えのソースを間違いました。

こんな感じのことをしたいのです。

int main()
{
    char c[50];

    test(c);
}

void test(char *c)
{
    char str[50] = "test";

    // ここでXXXに[c]のサイズを指定したい
    strcpy_s(c,XXX,str);
}


keichan  2006-12-05 01:18:37  No: 63811

C言語では"ポインタ"変数にしてしまった状態で配列のサイズを取得する方法はありません。
test関数の引数に配列のサイズも渡すようにしてください。


PATIO  2006-12-05 01:25:33  No: 63812

追記するなら、
strcpy_sと言う関数にサイズが付けられたのは、
正に同じ理由でポインタで引き渡された先のサイズを取得する方法が無い為、
チェックしようにもチェックできないからです。
但し、同じ理由で引き渡したサイズがバッファのサイズを正しく示していない
場合は、せっかくのstrcpy_sも期待した効果は出ないと思います。
keichanさんが書かれている通り、test関数自体にサイズを引き渡す為の
引数を追加してそれを使うしかないと思います。
どちらにしても正確なサイズが引き渡されなければ、効果は期待できないのですけれど。


メルティー  2006-12-05 01:25:50  No: 63813

keichanさん、返信ありがとうございます。

>C言語では"ポインタ"変数にしてしまった状態で配列のサイズを取得する方法はありません。
やっぱりそうですか・・・
関数にサイズを渡すようにします。
ありがとうございました。


メルティー  2006-12-05 01:28:25  No: 63814

PATIOさん、返信ありがとうございます。

>strcpy_sと言う関数にサイズが付けられたのは、
>正に同じ理由でポインタで引き渡された先のサイズを取得する方法が無い為、
>チェックしようにもチェックできないからです。
こんな理由があったんですね、
くわしい情報ありがとうございます。


Blue  2006-12-05 01:42:03  No: 63815

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


PATIO  2006-12-05 02:20:16  No: 63816

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>っていうのは普通にやりますし、
どの辺に載っていたのか知りたいのでぜひ教えてください。


Blue  2006-12-05 02:37:58  No: 63817

>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


Blue  2006-12-05 09:21:42  No: 63818

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)

であることがわかります。
同様にして、それぞれのマクロの定義を確認することができます。


PATIO  2006-12-05 22:21:01  No: 63819

マクロ展開の結果がこうなるわけですね。
了解です。


メルティー  2006-12-05 22:34:33  No: 63820

Blueさん、返信ありがとうございます。

>template <size_t size>
>void test(
>   char (&c)[size],
>) // C++ only
>{
template、使ったことありません・・・
よく使われるものなんでしょうか?
template調べてみます。

いつの間にか、何か難しい話になってますね。


Blue  2006-12-05 22:47:13  No: 63821

>template、使ったことありません・・・
templateは完全に C++ の話になってしまいます。
まぁ、VC++2005ってことで一応ありかなと。

>よく使われるものなんでしょうか?
リストのようなコンテナクラスではよく使いますね。
(STLならstd::vectorとかstd::listとか、MFCならCArrayとかCListとか)

>template調べてみます。
C++の入門書ならどれも載っているのかな。
Google等で検索してみても、参考になるサイトはたくさん見つかると思います。


メルティー  2006-12-06 02:31:42  No: 63822

Blueさん、返信ありがとうございます。

手元にC++の入門書もネット環境もありますので、
色々と調べてみようと思います。


kure  2006-12-06 03:05:55  No: 63823

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;
}

じゃだめなんですかね?


kure  2006-12-06 03:08:10  No: 63824

配列の要素数を渡したくないけど、
渡さなきゃだめですか?って質問だった orz

↑のは引数に配列の数思いっきり書いてるから
質問者の意図からはずれてますね。
申し訳ないm(_ _)m


Blue  2006-12-06 03:10:05  No: 63825

>size_t arg_size = sizeof(*arg) / sizeof(*arg[0]);
これって意味があるのでしょうか?

>void test( char (*arg)[50] )
50とここで固定にしているから、arg_sizeは50なのは決まっているのでは
ないのでしょうか?

手元にVS2005環境がないので間違ったこと抜かしているかもしれませんけど。。。


kure  2006-12-06 03:50:59  No: 63826

> これって意味があるのでしょうか?
意味はないですね。
50って限定してますし。
一応(配列の)ポインタ渡して配列の数が取れるよって
例を上げてみたんですが、そもそも質問の意図からはずれてますし。。。


kure  2006-12-06 03:53:40  No: 63827

>> これって意味があるのでしょうか?
> 意味はないですね。

強いて言えば

void test( char (*arg)[100] )

に変わったときにstrcpy_sのほうを書き換えなくて済むってことくらいですね。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加