Discussion:
sprintfとswprintfとwsprintfの使用上の違いについて質問
(too old to reply)
unknown
2005-10-18 08:27:03 UTC
Permalink
MSDOSのときは
sprintfの便利さが気に入ってよく使っていました。
Windowsになってsprintf以外にswprintfとwsprintfが出てきました。
wはWindowsかwideの意味だと思いますが、もう一つしっくりきません。
シングルバイト文字列、ワイド文字列、マルチバイト文字列や、
ANSI(SBCS)、MBCS、Unicodeの文字セットと出て来て混乱しています。
取りあえずはwsprintfを優先して使っていますが、
元々MSDOSの時のソースでは半角文字でも、全角文字でもsprintfをひとつで済みました。
Windows用に修正する時にsprintfをそのままで置いとこうか、wsprintf
に置き換えようか、はた又swprintfを使おうかと迷ってしまいます。
どなたかsprintfとswprintfとwsprintfの用法上の違いが分かれば
教えていただけないでしょうか。
なお、Win32APIでコーディングとの前提です。
Takeshi SHIGIHARA
2005-10-18 08:54:18 UTC
Permalink
Post by unknown
Windowsになってsprintf以外にswprintfとwsprintfが出てきました。
wはWindowsかwideの意味だと思いますが、もう一つしっくりきません。
こちらは swprintf (Wがあとのほう、sprintfといっしょに説明されている)
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vclib/html/_crt_sprintf.2c_.swprintf.asp

こちらは wsprintf (Wが先になるほう)
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/jpwinui/html/_win32_wsprintf.asp



----- Takeshi SHIGIHARA
***@tka.att.ne.jp
***@po.jah.ne.jp -----
うまい、早い、安い/2つだけ選べ--RFC1925.
Takeshi SHIGIHARA
2005-10-18 13:08:54 UTC
Permalink
私の場合にはWin32 API'だけ'のコーディングというのは、滅多に
ないですね。たいてい、C/C++ランタイムライブラリと併用します。
いや、、たいていじゃなく常に、ですね。
Win32 APIだけしか使用できない場合というのは、ちょっと思い
つきません。Device driverとかの、特別な場合かな。

文字コードに関して、Windows上でのおおよその理解ですが
 ・ANSI(SBCS)は英数字だけを使うこと
 ・シフトジス(MBCS)は、MS-DOSと同じ文字コード
 ・ワイド文字とはUNICODEと呼ばれる、常に16ビットで1文字を表すコード
と思えば、合っています(……よね?)
EUC-JPなども多バイト文字の一種ですが、これはWindows上で
ソースコードになることは、まず無いでしょう。UTF-8とかの
ユニコードシステムもありますが、このへんになると私は実は
理解がアヤフヤだったり。

NT/XPシステムの内部では、UNICODEが基本となっているので
MBCSは遅くなると言う人もいますが、今のマシンでは大した
時間差は生じないと思います。

多国語を前提としておらず、日本語しか使わないし、日本の
マシンでしか動作させる気もないよ、というのなら、シフトジス
のままで、これまでどおり sprintf を使っているのが楽です。

wsprintfはWin32 APIなのですが、正直なところ、私はあまり
使っていません。wsprintfの説明にもあるとおり、実は制限が
多くて、少々使いづらいのです。
swprintf はワイド文字(つまりUNICODE)用なので、こっちを
使うことは、あまり多くないのではないでしょうか。

----- Takeshi SHIGIHARA
***@tka.att.ne.jp
***@po.jah.ne.jp -----
ブタも投げれば空を飛ぶ--RFC1925.
unknown
2005-10-19 06:38:02 UTC
Permalink
ありがとうございました。
お話の趣旨ではsprintfをわざわざ書きかえる必要がないと云うことになりますが
そう理解してよろしいでしょうか。
おっしゃる通り、日本語圏内だけのソフトを想定しているのでUnicodeは
必要ないと考えています。
NT/XP系のWinowsではUnicodeを想定しているとのことですが、
例えば文章を書きこんだフロッピーが書きこんだWindowsの体系で異なる場合はどうなるのでしょう。OSの方で自動的に読み替えてくれるのでしょうか。
例えばUnicodeで文字列123と書かれたとしますと0x31, 0x32, 0x33ではなくて
0x31,0x00,0x32,0x00,0x33,0x00となる?のではそれを文字列で読みこむと
0x00はヌルですから文字列の終わりと見なされ、1しか表示されなくなるのは。
 私の理解では1024バイト以下の文字列の場合はwsprintfを使って置いた
方がNT/XP系も95/98系も両方に対応できると云う意味で有利かなと理解
していますが、もうひとつ確信がありません。
まだ、不都合が起こった例にはぶつかっていないので実感がないのです。
 swprintfはUnicode専用だと云うことは理解しています。
Post by Takeshi SHIGIHARA
私の場合にはWin32 API'だけ'のコーディングというのは、滅多に
ないですね。たいてい、C/C++ランタイムライブラリと併用します。
いや、、たいていじゃなく常に、ですね。
Win32 APIだけしか使用できない場合というのは、ちょっと思い
つきません。Device driverとかの、特別な場合かな。
文字コードに関して、Windows上でのおおよその理解ですが
 ・ANSI(SBCS)は英数字だけを使うこと
 ・シフトジス(MBCS)は、MS-DOSと同じ文字コード
 ・ワイド文字とはUNICODEと呼ばれる、常に16ビットで1文字を表すコード
と思えば、合っています(……よね?)
EUC-JPなども多バイト文字の一種ですが、これはWindows上で
ソースコードになることは、まず無いでしょう。UTF-8とかの
ユニコードシステムもありますが、このへんになると私は実は
理解がアヤフヤだったり。
NT/XPシステムの内部では、UNICODEが基本となっているので
MBCSは遅くなると言う人もいますが、今のマシンでは大した
時間差は生じないと思います。
多国語を前提としておらず、日本語しか使わないし、日本の
マシンでしか動作させる気もないよ、というのなら、シフトジス
のままで、これまでどおり sprintf を使っているのが楽です。
wsprintfはWin32 APIなのですが、正直なところ、私はあまり
使っていません。wsprintfの説明にもあるとおり、実は制限が
多くて、少々使いづらいのです。
swprintf はワイド文字(つまりUNICODE)用なので、こっちを
使うことは、あまり多くないのではないでしょうか。
----- Takeshi SHIGIHARA
ブタも投げれば空を飛ぶ--RFC1925.
とっちゃん
2005-10-19 07:23:36 UTC
Permalink
とっちゃんです。


問題点が3つに分かれていますね。
1. 同機能の関数は APIを使うべきか、CRT(C-Runtime)を使うべきか。
2. UNICODE 対応はどうするべきか。
3. ファイルの中のUNICODEデータはどう考えるか。


1. API と CRT
こちらは、正直に言えばどっちでもいいと思います。
プログラム全体でどちらかに統一するというのが一番よいのですが、
wsprintf には %f が扱えないなどの制約もあります。
また、書式解析部分は、そのほかのprintf 系でも利用されていますので
どれか一つでも使っていれば、部分的にwsprintf を導入しても効果はありません。

なお、CRTではなくAPIにするとした場合の利点は、EXEサイズが小さくなること
OSの設定を受けなくなること(ただし、CRTのLocaleは影響する)というだけです。


2. UNICODE対応
これは、9x系での動作をサポートするならやらないほうがよいと思います。
UNICODE APIの再配布セットなどもありますが、最終的な表示処理では
完全なるUNICODE化はできません(フォントも同様)。

そのため、内部処理がすべてUNICODEであったとしても最後の表示部分で
ANSI/DBCS になってしまうため、状況によっては意図しない不具合が出ることもあります。

UNICODEにしなければ対応できない部分「のみ」UNICODEにすればよいと思います。

OSレベルで見れば、NT系(2000/XPおよびVista)は、OSサイドはすべてUNICODEベースで
実装されていますが、9x系(95/98/SE/ME)は、すべてがANSI(DBCS)で実装されています。
国際化対応を考えていないようなので気にしなくてもよいと思いますが、9x系の英語版はDBCSにすら
対応していないという点にも注意が必要です(英語版でwsprintf( ..."ホゲホゲ表", ... )とかやると痛い目にあいます)。


3. ファイルの中の文字列データ
ファイルの読み書きについて言えば、OSの影響は受けません。
テキストファイルは、バイナリファイルの特殊フォーマットの一つに過ぎません。
CRT レベルでは、より扱いやすいように加工する仕組みが入っていますが(\r\nを\nだけにするなど)
それはあくまでも C 言語のレベルの話であって、OSにとって見ればファイルのデータは
単なるバイトイメージの塊でしかありません(それをどう扱うかは、OSビルトインを含むアプリケーションの問題)。

ただし、UNICODEのテキストファイルで言えば、BOMというヘッダーをつけることが強く推奨されていますので
ほとんどのUNICODEが扱えるテキストエディタではBOMをつけて保存しています。

ですので、BOMがあるかを確認すれば、UNICODE非対応アプリでも誤動作することはありません。


// とっちゃん(高萩 俊行)
// http://tocchan.cocolog-nifty.com/
// Microsoft MVP for Windows SDK (Oct 2005 - Sept 2006)

Loading...