ReadConsoleOutput()の挙動について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
usao
記事: 1889
登録日時: 11年前

ReadConsoleOutput()の挙動について

#1

投稿記事 by usao » 10年前

環境 : Win7 Home(64bit) , VS2012 Express

Win32APIの ReadConsoleOutput() についてです.
MSDNによると,この関数は,
情報を取得したい領域矩形をコンソールスクリーンバッファからはみ出す形に指定した場合でも
よろしくやってくれる(はみ出さない部分についてのみの情報をくれる)ことになっているのですが,
プロジェクトが「Unicode文字セットを使用する」設定になっているとうまくいかないようで困っております.

以下のコードを
「マルチバイト文字セットを使用する」設定でビルド→実行した場合だと
ただしく はみ出さない部分についての情報を取得できています.
(結果スクリーンショット添付します.これが所望の動作です)

しかし,前述のように設定を「Unicode~」に変えると正しく取得できません.
なぜか結果の一部に 0 が入れられてしまうのです.
(結果とデバッガで受取バッファ内を見たところのスクリーンショット添付します)

原因や対応策(Unicode設定で所望の結果を得る方法)についてご教授いただきたく,お願い申し上げます.
► スポイラーを表示
添付ファイル
Unicodeデバッガ.png
Unicodeデバッガ.png (31.1 KiB) 閲覧数: 4016 回
Unicode実行結果.png
Unicode実行結果.png (37.08 KiB) 閲覧数: 4016 回
MBCS実行結果.png
MBCS実行結果.png (39.43 KiB) 閲覧数: 4016 回

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: ReadConsoleOutput()の挙動について

#2

投稿記事 by h2so5 » 10年前

僕のマシンだと実行結果が異なります。
環境 : Win8.1 , VS2010
添付ファイル
スクリーンショット 2014-05-05 18.33.35.png
MBCS実行結果
スクリーンショット 2014-05-05 18.33.35.png (9.41 KiB) 閲覧数: 4006 回
スクリーンショット 2014-05-05 18.31.23.png
Unicode実行結果
スクリーンショット 2014-05-05 18.31.23.png (9.41 KiB) 閲覧数: 4006 回

アバター
usao
記事: 1889
登録日時: 11年前

Re: ReadConsoleOutput()の挙動について

#3

投稿記事 by usao » 10年前

>僕のマシンだと実行結果が異なります。

ご確認いただきありがとうございます.

MBCSならOKというわけでもないのですね.
「はみ出さないように指定する」しかないのでしょうか…

アバター
へにっくす
記事: 634
登録日時: 12年前
住所: 東京都

Re: ReadConsoleOutput()の挙動について

#4

投稿記事 by へにっくす » 10年前

MBCS/Unicodeの違いは文字コードなのはわかりますよね?
なのに何でコンソールの文字コードは変えてないのですか。
GetStdHandleする前に、以下のコードを追加して文字コードを切り替えてください。
※VS2012 Win7の環境で確認。

コード:

#ifdef _UNICODE
	::SetConsoleOutputCP(65001); // UTF-8
#else
	::SetConsoleOutputCP(932); // Shift-JIS
#endif
SetConsoleOutputCP関数 - MSDN

※Win8.1 VS2013でやったらこれでもダメでした(ただしMBCS/Unicodeの切り替えでは同じ結果です。なぜか3行目を取得できないので、別の問題?バグかしら・・・)。
written by へにっくす

アバター
usao
記事: 1889
登録日時: 11年前

Re: ReadConsoleOutput()の挙動について

#5

投稿記事 by usao » 10年前

>GetStdHandleする前に、文字コードを切り替えてください。

ありがとうございます.
SetConsoleOutputCP()を使うと とりあえず私の環境では
前述のコードが「所望の動作」になることを確認いたしました.
(GetConsoleOutputCP()で調べてみたところ,
 プロジェクトの文字コードの設定に関わらずデフォルト状態だと 932 が返されていました.)

SetConsoleOutputCP()に渡す引数の値は何ぞや?という点については,
MSDNのSetConsoleOutputCP()の英語版の方
http://msdn.microsoft.com/en-us/library/ms686036
には,Code Page Identifiers というページ
http://msdn.microsoft.com/en-us/library/dd317756
へのリンクがあり,そこに書かれていました.

#何やらフォントの具合も変わる?(65001にしたら文字が太い)ようです


>※Win8.1 VS2013でやったらこれでもダメでした
おっと,この場合,[解決]とは行かないのかな.

アバター
へにっくす
記事: 634
登録日時: 12年前
住所: 東京都

Re: ReadConsoleOutput()の挙動について

#6

投稿記事 by へにっくす » 10年前

usao さんが書きました:#何やらフォントの具合も変わる?(65001にしたら文字が太い)ようです
それは太いのではなく、UTF-8対応のフォントに自動的に切り替わるからですね。
usao さんが書きました:>※Win8.1 VS2013でやったらこれでもダメでした
おっと,この場合,[解決]とは行かないのかな.
Win8.1での現象は、質問の趣旨とはまた別の問題かと思いますよ。
MBCS/Unicodeの切り替えでも変わらないし。
MSDN forumに投稿した方がいいかも。
(・・・ってusaoさんに言っても仕方がないか ^^;)
written by へにっくす

アバター
usao
記事: 1889
登録日時: 11年前

Re: ReadConsoleOutput()の挙動について

#7

投稿記事 by usao » 10年前

>それは太いのではなく、UTF-8対応のフォントに自動的に切り替わるからですね。

その関係なのか,65001にしたら
WriteConsole()で日本語を含む文字列を出力できなくなってしまいました T_T
フォントの設定とかがいるのかも…
(しかしWriteConsoleOutputCharacter()のほうは元気に日本語出力してます.なぜか.)
オフトピック
関係あるのか無いのかわかりませんが,ググっていたらこんなのがあり,
http://stackoverflow.com/questions/1088 ... ws-console
ここでは SetConsoleOutputCP()ではなく _setmode() とかいうのを使う話がされているようで…?

うーん,MBCSの世界に引きこもりたい……

アバター
へにっくす
記事: 634
登録日時: 12年前
住所: 東京都

Re: ReadConsoleOutput()の挙動について

#8

投稿記事 by へにっくす » 10年前

これ参考になるかな。
XPだと隠しAPIを使わないとフォントを変更できないらしい。Vista以降なら公開されているAPIがあるが
Win32APIでコンソールをゴリゴリと

・・・ってーか趣旨と変わってないかw
オフトピック
Unicode使わなければならない理由でもあるの?
written by へにっくす

アバター
usao
記事: 1889
登録日時: 11年前

Re: ReadConsoleOutput()の挙動について

#9

投稿記事 by usao » 10年前

>・・・ってーか趣旨と変わってないかw

SetConsoleOutputCP()を使う方法で 他の事に副作用(?)が出てしまったので
このまま解決でいいのかなぁ,とか思ったので…

まぁ 最初のコードについては こちらの環境では動作結果が改善したということで
[解決]をつけておきます.


とりあえず直近ではMBCSの世界に逃げておいて,
コンソール+Unicode の色々な問題については 今後,時間があるときにでも調べてみようかと思います.

ありがとうございました.

Mana

Re: ReadConsoleOutput()の挙動について

#10

投稿記事 by Mana » 10年前

こちらではコマンドプロンプトのコードページは932のままでUnicodeでもMBCSでもちゃんと表示できたけども。
環境 : Win7 Ultimate(64bit) , VS Express 2013 for Desktop

ただし画面に表示されているのではなく画面バッファから取得するらしく
No.1のコードの最初に
::system("cls");
を加えることで安定した。
こちらの環境はバッファ大きくしてるから。

Mana

Re: ReadConsoleOutput()の挙動について

#11

投稿記事 by Mana » 10年前

IDEやエクスプローラーから起動するなら::system("cls")関係ありませんね。

こちらでは常に正常なので検証不可ですがロケールが関係するのかもしれないと思い付いたので投稿。

閉鎖

“C言語何でも質問掲示板” へ戻る