
http://msdn.microsoft.com/ja-jp/library/td1esda9 …
を見て、たとえば以下のような関数を書いたとします。
TCHAR* fn;
void OMG(LPCTSTR c){
int bytes( ( _tcslen(c) + 1 )*sizeof(TCHAR) );
if ( fn = (TCHAR*)malloc( bytes ) ) _tcscpy_s( fn, bytes, c ); //実行しないでください
else return;
/* fnを使用 */
free(fn); fn=0;
}
これ、マルチバイトだと正常に出来るのですが
なぜかUnicodeだと落ちてしまいました。
第2引数の説明は
コピー先の文字列バッファのサイズ。
<英語版でも>
Size of the destination string buffer.
となっていますが、その上に
numberOfElements
って書いてあるのでまさかと思い
サイズではなく文字数に変えたら、どうも正常に動作するようになったようです。
とくに_sがつく関数は文字数だったりバッファサイズだったりまちまちな感がもともとあるのに、しかも
こういうところでこういうことがあると厳しいものがあるのですが
これは本当に誤植なのでしょうか?
また、かなり稀なケースであり本当に誤植だとしたら、MSDNの他の文字列操作関数には記述の誤りがあるものはありますか?
No.2ベストアンサー
- 回答日時:
C++のtemplateを使ったstrcpy_s,wcscpy_sは
template <size_t size>
errno_t strcpy_s(
char (&strDestination)[size],
const char *strSource
); // C++ only
template <size_t size>
errno_t wcscpy_s(
wchar_t (&strDestination)[size],
const wchar_t *strSource
); // C++ only
となっています。
これをみると、sizeは「配列数」ということになります。
ですので、「numberOfElements」のさす意味そのもので「要素の数」(≠文字数)という解釈になります。
ちなみに、Unicodeでも1文字2バイトとは限りませんので
一概に文字数ともいえません。
(サロゲート で検索してみてください。)
>TCHAR c[100];
>
>if ( fn = (TCHAR*)malloc( sizeof c ) ) _tcscpy_s( fn, >sizeof(c)/sizeof(TCHAR), c );
>
>とか
>_tcscpy_s( fn, 100, c );
まぁ、結果的にあっていますが、fnに格納するときにバッファが足りているかをみるのをcを使うのはよろしくないかなと。
>int len( _tcslen(c) + 1 );
>if ( fn = (TCHAR*)malloc( len*sizeof(TCHAR) ) ) _tcscpy_s( fn, len, c );
のほうがよいですね。
まぁ、cに格納されている文字列を新しい領域をmallocしてコピーするのであれば、_tcsdupで
TCHAR* fn = _tcsdup(c);
と記述できます。
http://msdn.microsoft.com/ja-jp/library/y471khhc …
>Unicodeでも1文字2バイトとは限りません
そうだったのですか
調べてみたら色々な方式があるようですね。
しかし、いずれにしても
>>int len( _tcslen(c) + 1 );
>>if ( fn = (TCHAR*)malloc( len*sizeof(TCHAR) ) ) _tcscpy_s( fn, len, c );
>のほうがよいですね。
ということは、sizeof(TCHAR)を使えばマルチバイトのバイト数と同じように判定できる、と考えて良いということですね。
>TCHAR* fn = _tcsdup(c);
こんな便利な関数があったのですね
色々と詳しいところありがとうございます♪
No.1
- 回答日時:
UNICODEでは1文字が何バイトになるか…という辺りが規定できないのでしょう。
Win32APIでも、ANSI版は「バイト数」、UNICODE版は「文字数」で扱うものが多いです。
GetModuleFileName()など…
>nSize
>[入力]lpFilename バッファのサイズを、TCHAR 単位で指定します。パス名とファイル名がこのバッファより大きかった場合、この関数は文字列を切り捨てます。
「TCHAR 単位」というのが、バイト数ではない…というコトになります。
ありがとうございます。
TCHAR単位ってちゃんと書いてあればどうコードを書けばいいかちゃんと判断出来ますが
http://msdn.microsoft.com/ja-jp/library/ce3zzk1k …
http://msdn.microsoft.com/ja-jp/library/eywx8zcx …
このへんは文字数って書いてあるのでこれでも判断できます
http://msdn.microsoft.com/ja-jp/library/8e46eyt7 …
これも1 バイト文字またはワイド文字の数と書いてあるので(ANSIでは1バイト文字の数なのかバイト数なのかといえば後者のような気がしますが(まだ試していません))
少なくともUnicodeではバイト数ではないと判断できます。
う~ん
両方対応するように一気に手直しした際、その中で
_tcscpy_s先に見ちゃったから
まちまちだと思ってしまったのかもしれませんが
実際には、おっしゃる通り
表記が一律でないだけで(ほぼ、あるいは全部かも)
>ANSI版は「バイト数」、UNICODE版は「文字数」
のような感じがしますね。
表記上そう読めなかったら検証してみることにします。
現状はUnicodeは2バイトのはずですし
上記コードは
int len( _tcslen(c) + 1 );
if ( fn = (TCHAR*)malloc( len*sizeof(TCHAR) ) ) _tcscpy_s( fn, len, c );
こういった具合に直しておけば問題はないはず。
また、こういう場合でも
TCHAR c[100];
if ( fn = (TCHAR*)malloc( sizeof c ) ) _tcscpy_s( fn, sizeof(c)/sizeof(TCHAR), c );
とか
_tcscpy_s( fn, 100, c );
といった具合にすればOK
と、思うのですが、コード側の対処法としてはこんな感じの考え方でOKでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
c++std::string型をTCHARに変換したい!
C言語・C++・C#
-
strncpyと_tcsncpy_sのヌルの扱いが違う点
C言語・C++・C#
-
TCHAR文字列内の検索について
C言語・C++・C#
-
-
4
ダイアログ表示時にチェックボックスにチェックされている状態にするには?
C言語・C++・C#
-
5
ラベル(スタティックテキスト)内での改行。
C言語・C++・C#
-
6
メモリリークの件
C言語・C++・C#
-
7
CStringのFindで文字列検索を行いたいのですが
C言語・C++・C#
-
8
VC++スレッドの正しい終了のさせかた
C言語・C++・C#
-
9
読み込み中にアクセス違反が発生しました、と出ます。これを回避することは
C言語・C++・C#
-
10
Visual Studioのstrcpy_sについて
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
_tcscpy_s(wcscpy_s)の第二引数...
-
C#でstringをポインタとして渡す
-
nullと""、\\0とEOFの違いにつ...
-
[C++]WCHARの1文字目しか表示で...
-
構造体→文字列→構造体 をする方法
-
プログラムによく出てくるst...
-
CStringからchar*への型変換に...
-
リッチテキストボックスの中身...
-
「#undef」と「#define」の使い...
-
C# Listを使わずに2次元配列の...
-
allocってなんですか?
-
TCHAR文字列内の検索について
-
C言語 配列の長さの上限
-
ExcelVBAでのkernel32(64bit)
-
C言語のポインタに直接アドレス...
-
VBAのプログラムで、DIAG = 1# ...
-
ExcelVBAで質問です。離れた二...
-
NASMかNASKの文法の本
-
Excelですべての組合せ(重複組...
-
C# DataGridView のヘッダーセ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
nullと""、\\0とEOFの違いにつ...
-
WSH(VBS)でJSONの文字列を読み...
-
%dなどの違い
-
シリアル通信で0x00を送信した...
-
C++で入力した文字列から数字を...
-
プログラムによく出てくるst...
-
TCL言語で文字列検索方法を教え...
-
16進数を2文字ずつ配列に格納し...
-
VB6.0でのバイナリデータの扱い...
-
C#でstringをポインタとして渡す
-
c#で他のアプリの文字入力フォ...
-
バイナリファイル中の日本語文...
-
VBA-DLLの引数受け渡しについて
-
構造体→文字列→構造体 をする方法
-
_tcscpy_s(wcscpy_s)の第二引数...
-
アルファベットの出て来た回数
-
引用符と二重引用符
-
char型配列の最大要素数
-
Excelシートを固定長のテキスト...
-
binaryに対して正規表現を適用...
おすすめ情報