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で質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- 数学 関数列の収束について 次の問題を教えて欲しいです。 区間[0,1) の関数列fnと関数f(x)につい 1 2022/06/01 08:33
- Visual Basic(VBA) 【マクロ】フォルダにファイルが1つも無い時に、ファイルがありませんとメッセージを表示する 4 2022/08/28 08:48
- Excel(エクセル) 1つのファイルを3つのフォルダにファイル名を【明日の日付】にして、コピーをしたい 2 2022/12/21 17:43
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- Excel(エクセル) 【マクロ】フォルダAからダBへファイルを、ファイルの更新日時の条件で、1つづつ移動するには? 3 2022/08/25 09:56
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# leetcode 155 minstack 1 2022/05/07 16:43
- Excel(エクセル) マクロのコードを、少しでも削って短くしたい 3 2022/08/30 07:46
このQ&Aを見た人はこんなQ&Aも見ています
-
餃子を食べるとき、何をつけますか?
みんな大好き餃子。 ふと素朴な疑問ですが、餃子には何をつけて食べますか? 王道は醤油とお酢でしょうか。
-
秘密基地、どこに作った?
小さい頃、1度は誰もが作ったであろう秘密基地。 大人の今だからこそ言える、あなたの秘密基地の場所を教えてください!
-
遅刻の「言い訳」選手権
よく遅刻してしまうんです…… 「電車が遅延してしまい遅れました」 「歯医者さんが長引いて、、、」 「病院が混んでいて」 などなどみなさんがこれまで使ってきた遅刻の言い訳がたくさんあるのではないでしょうか?
-
おすすめのモーニング・朝食メニューを教えて!
コメダ珈琲店のモーニング ロイヤルホストのモーニング 牛丼チェーン店の朝食などなど、おいしいモーニング・朝食メニューがたくさんありますよね。
-
14歳の自分に衝撃の事実を告げてください
タイムマシンで14歳の自分のところに現れた未来のあなた。 衝撃的な事実を告げて自分に驚かせるとしたら何を告げますか?
-
CStringをwchar_tに変換したい
C言語・C++・C#
-
CString から LPCTSTRの型に変換
C言語・C++・C#
-
CStringのFindで文字列検索を行いたいのですが
C言語・C++・C#
-
-
4
CStringからchar*への型変換について教えてください。
C言語・C++・C#
-
5
CStringの文字列検索&抜き出しについて
C言語・C++・C#
-
6
VC++ 2008 EXPRESS _T"識別子がみつかりません"
C言語・C++・C#
-
7
WaitForSingleObjectの使い方について
C言語・C++・C#
-
8
エディットボックスで改行
その他(プログラミング・Web制作)
-
9
std::stringからLPCWSTR型への変換
C言語・C++・C#
-
10
画面を強制的に再描画させる方法
C言語・C++・C#
-
11
(マルチスレッド)_beginthreadexに複数の引数を渡す
C言語・C++・C#
-
12
c++std::string型をTCHARに変換したい!
C言語・C++・C#
-
13
文字列がNULLか空文字列かの判定
C言語・C++・C#
-
14
CWnd::EnableWindow()の扱い方
C言語・C++・C#
-
15
メモリリークの件
C言語・C++・C#
-
16
charからLPTSTRへの変換方法
C言語・C++・C#
-
17
INT64対応のprintf系関数はありますか?
C言語・C++・C#
-
18
ボタンの表示の色、フォントを変更したい
C言語・C++・C#
-
19
VC++スレッドの正しい終了のさせかた
C言語・C++・C#
-
20
wsprintf関数の使い方について
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
- ・お風呂の温度、何℃にしてますか?
- ・とっておきの「まかない飯」を教えて下さい!
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・いけず言葉しりとり
- ・土曜の昼、学校帰りの昼メシの思い出
- ・忘れられない激○○料理
- ・あなたにとってのゴールデンタイムはいつですか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
アルファベットをカウント、
-
nullと""、\\0とEOFの違いにつ...
-
C#でstringをポインタとして渡す
-
文字コードによる表記
-
binaryに対して正規表現を適用...
-
%dなどの違い
-
シリアル通信で0x00を送信した...
-
c言語によって文字列を逆順する...
-
C++で入力した文字列から数字を...
-
16進数を2文字ずつ配列に格納し...
-
VB6.0でのバイナリデータの扱い...
-
プログラムによく出てくるst...
-
_tcscpy_s(wcscpy_s)の第二引数...
-
WSH(VBS)でJSONの文字列を読み...
-
数字の入った配列をファイルへ...
-
TCL言語で文字列検索方法を教え...
-
C言語 配列の長さの上限
-
CStringからchar*への型変換に...
-
Integer変数をカラにしたいので...
-
セグメントエラー
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プログラムによく出てくるst...
-
nullと""、\\0とEOFの違いにつ...
-
C++で入力した文字列から数字を...
-
WSH(VBS)でJSONの文字列を読み...
-
C#でstringをポインタとして渡す
-
TCL言語で文字列検索方法を教え...
-
%dなどの違い
-
VB6.0でのバイナリデータの扱い...
-
16進数を2文字ずつ配列に格納し...
-
[C++]WCHARの1文字目しか表示で...
-
char型配列の最大要素数
-
_tcscpy_s(wcscpy_s)の第二引数...
-
シリアル通信で0x00を送信した...
-
Shift_JIS(16進)を文字に変換す...
-
sprintf関数について教えて下さ...
-
バイナリファイル中の日本語文...
-
構造体→文字列→構造体 をする方法
-
引用符と二重引用符
-
C言語の勉強しています。すみま...
-
文字列にある特定文字の数
おすすめ情報