C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

メッセージボックスでの改行時に何を使いますか?

[トピック内 15 記事 (1 - 15 表示)]  << 0 >>

■85710 / inTopicNo.1)  メッセージボックスでの改行時に何を使いますか?
  
□投稿者/ 魔界の仮面弁士 (1461回)-(2017/11/15(Wed) 12:42:50)

分類:[雑談] 

No85699 (ぶなっぷ さん) の投稿
> ErrMsg += "\nえらー1";

No85701 (PANG2 さん) の投稿
> MessageBox.Show(string.Join("\n", errList));


アンケートというか雑談。
皆さん、メッセージボックスに改行を含める際、どの文字を使っていますか?


言語仕様的には、C# においては
 "\r" → CR
 "\n" → LF
であり、Visual Basic においては
 vbCr → CR
 vbLf → LF
 vbCrLF → CR+LF
 vbNewLine → ControlChars.NewLine 相当
 ControlChars.NewLine → Environment.NewLine 相当
であると認識しています。

Environment.NewLine は、Windows では CR+LF 相当ですね。

Console.WriteLine や StringBuilder.AppendLine がそうであるように、
Windows の改行は、基本的に CR+LF を使う仕様となっているため、
VB からは vbCrLf を用いることが自分は多かったのですが、
C# だと \n を使うことが多そうなので、何が望ましいのかと気になった次第。


ファイル出力時などでは、改行の違いは重要ですよね。
メモ帳だと、0D,0A や 単独 0A は改行として扱われるのですが、
0D 単独だと、改行として表示されませんし(ゼロ幅スペースのように見える)。


一方メッセージボックスは、CR / LF / CR+LF / LF+CR のいずれも
単一の改行として表示されるようなのですが、メッセージ内容を
 Ctrl + C
でコピーすると、CR と LF が区別されてクリップボードに入るため、内部的には区別されます。
(コピーできるのは、Windows 2000 以降限定だったかな? NT4 では Ctrl+C できなかった記憶が)

ただ、何故か MessageBox には \n が CR+LF に展開されてしまうようなので、
皆さんどうしているのかなー、と。Console クラス等では \n → LF なのに。

MessageBox.Show("/LF=\n/CR=\r/CRLF=\r\n/LFCR=\n\r/LS=\u2028/PS=\u2029/End");

 \n → U+000D,U+000A
 \r → U+000D
 \r\n → U+000D,U+000D,U+000A
 \n\r → U+000D,U+000A,U+000D
 \u2028 → U+2028
 \u2029 → U+2029
引用返信 編集キー/
■85715 / inTopicNo.2)  Re[1]: メッセージボックスでの改行時に何を使いますか?
□投稿者/ とっちゃん (473回)-(2017/11/15(Wed) 14:50:17)
No85710 (魔界の仮面弁士 さん) に返信

> 皆さん、メッセージボックスに改行を含める際、どの文字を使っていますか?

どこに渡す場合でも "\n" ですね。
例外は、テキストファイルをバイナリモードでオープンした場合だけ。

コンソールが "\n を改行とするのは、MS-DOS時代からの仕様です。

MS-DOS時代からの仕様で
テキストファイルの改行は相互運用のため "\r\n" とするとなっており(相互運用は非MS系OS)
オンメモリの文字列データの改行はメモリ消費量節約と処理の軽量化のために "\n" とする
となっています。

なので、オンメモリデータとして処理されるコンソールにおける改行は"\n"のみとなっています。
最もコンソールが \n オンリーなのは主にデリミタ処理を簡素化するためだと思いますけどねw

で、このあたりがそのままずーっと継続されていて基本は "\n" です。

クリップボードに張り付けると \r\n になっているのは、よくわからないですがそういう仕様だからです。
今のリファレンスにも書いてありますが
「Text format. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data. Use this format for ANSI text.」
と書かれています。
なので、メッセージボックスで Ctrl+C したら \r\n になっているのは仕様ですね。

さらに言うと、SetWindowText(WM_SETTEXTメッセージ)には改行に関する規定はありません。

引用返信 編集キー/
■85719 / inTopicNo.3)  Re[1]: メッセージボックスでの改行時に何を使いますか?
□投稿者/ furu (133回)-(2017/11/15(Wed) 16:16:54)
No85710 (魔界の仮面弁士 さん) に返信

> 皆さん、メッセージボックスに改行を含める際、どの文字を使っていますか?

C#ですが、
復帰と改行の文字や順序の間違いも無いので
定義されているEnvironment.NewLineを使用しています。

古い人間なので、プリンタに送るイメージが強く
CR(復帰)だけとかLF(改行)だけだと気持ち悪いです。

よくインパクトプリンタでは
CR(復帰)だけで同じ文字列を印字し
太文字を作ってました。

引用返信 編集キー/
■85723 / inTopicNo.4)  Re[2]: メッセージボックスでの改行時に何を使いますか?
□投稿者/ 魔界の仮面弁士 (1465回)-(2017/11/15(Wed) 19:30:21)
No85715 (とっちゃん さん) に返信
> さらに言うと、SetWindowText(WM_SETTEXTメッセージ)には改行に関する規定はありません。

API 絡みだと、ワードラップによる折り返しを「CR+CR+LF」にするための
EM_FMTLINES によるソフト改行モードとか、EM_GETTEXTEX による
GT_USECRLF / GT_DEFAULT モードの切り替えなどが見つかりました。

しかし、MessageBox API での改行に関する情報は見当たらず…。orz

WM_SETTEXT の規定が見つからないので、このへん、意外と未定義っぽいですね。
複数行モードの EDITBOX と MessageBox で動きが異なるのも、歴史的な経緯によるものなのかな…。


> クリップボードに張り付けると \r\n になっているのは、よくわからないですがそういう仕様だからです。
とはいえ、SetClipboardData API 自体はコードを変換したりするわけでは無さそうですし、
どのようなバイナリとしてセットされるのかは、転送元の実装次第ですよね。


>> MessageBox.Show("/LF=\n/CR=\r/CRLF=\r\n/LFCR=\n\r/LS=\u2028/PS=\u2029/End");

上記と同じ文字列を TextBox に渡してみた場合は、"\r\n" の場所でしか改行されませんでした。
クリップボードに送られる内容も、"\r" 部は U+000D、"\n" 部は U+000A のままでした。
個人的には、MessageBox にも同じ仕様を期待していたのですけれどね。

一方、RichTextBox だとさらに動きが変わって、クリップボードの内容が
 リッチテキストパート
  2個の物理改行になったもの: "\n\r"
  1個の物理改行になったもの: "\n", "\r", "\r\n", "\u2029"
  1個のソフト改行になった物: "\u2028"
 プレーンテキストパート
  U+000D,U+000A になったもの: "\n", "\r", "\r\n", "\u2029", "\u2028"
  U+000D,U+000A,U+000D,U+000A: "\n\r"
という結果になるようです。



No85719 (furu さん) に返信
> 古い人間なので、プリンタに送るイメージが強く
> CR(復帰)だけとかLF(改行)だけだと気持ち悪いです。

自分も CR+LF で無いと落ち着かない派です。
(自分も古い人間…ってことですかね orz)


> 定義されているEnvironment.NewLineを使用しています。

エラーメッセージ内に改行が含まれる場合、改行コードとして
CR+LF を使うライブラリと CR を使うライブラリと LF を使うライブラリが
あるので、出力前に Environment.NewLine に統一するために

msg = (msg ?? "").Replace("\r\n", "\n").Replace('\r', '\n').Replace("\n", Environment.NewLine);

のような整形処理を入れています。

ただ、ファイルやデータベースに残す場合はこれで良いのですが、
MessageBox として表示する場合、先述のように
NewLine が U+000D,U+000D,U+000A になってしまう点が問題になります。
(EM_FMTLINES のソフト改行と同じコードですね)

なので、MessageBox への出力が必要な場合に限定して、
NewLine ではなく \n に変換して対処していたりします。正直面倒…。
引用返信 編集キー/
■85724 / inTopicNo.5)  Re[3]: メッセージボックスでの改行時に何を使いますか?
□投稿者/ shu (1066回)-(2017/11/15(Wed) 19:58:01)
No85723 (魔界の仮面弁士 さん) に返信

VBメインなのでCR+LFを使いますが、明示的に使うのも
どうかと思いEnvironment.NewLineを使っていましたが最近では
StringBuilderでメッセージを作成するようにして
改行はAppendLine
実際に文字列にするときにToString
という使い方になってます。
引用返信 編集キー/
■85725 / inTopicNo.6)  Re[1]: メッセージボックスでの改行時に何を使いますか?
□投稿者/ 魔界の仮面弁士 (1466回)-(2017/11/15(Wed) 21:39:23)
No85710 (魔界の仮面弁士) に追記
> メッセージボックスに改行を含める際、どの文字を使っていますか?

VBScript の WScript.Echo メソッドで追試。

Call WScript.Echo("/LF=" & vbLf & "/CR=" & vbCr & "/CRLF=" & vbCrLf & "/LFCR=" & vbLf & vbCr & "/End")

wscript.exe 経由での呼び出しだと、MsgBox と変わりありませんでした。
cscript.exe 経由での呼び出しで、標準出力に出力した場合は:
---------------
vbLf → 0D,0A
vbCr → 0D
vbCrLf → 0D,0A
vbLf & vbCr → 0D,0A,0D
---------------
と展開されました。

MsgBox と違って、CR+LF が 0D,0D,0A になることは無い様ですが、
LF が 0D,0A に展開されるという点は一緒ですね。まぁこれは想定通り。


なお、コンソールへの出力時は、
---------------
 0D → 改行はせずに、出力開始位置を左端に復帰させる。
 0A → 次の行に移り、出力開始位置を左端に復帰させる。
---------------
と言う動作となっており、"CR=" の行は次行の内容で上書きされます。
0D,0A は上記を組み合わせた動作なのでしょうが、結果的には 0A と同義ですね。



一方、VB6 の「Print # ステートメント」は完全に無加工でした。
---------------
vbLf → 0A
vbCr → 0D
vbCrLf → 0D,0A
vbLf & vbCr → 0A,0D
---------------

ただし、VB6 の「Print ステートメント」は、0A も 0D も 0D,0A も等しく
「次の行に移り、出力位置を左端に復帰させる」動作のようです。
Visual Basic for MS-DOS はどうだったんだろう。
引用返信 編集キー/
■85726 / inTopicNo.7)  Re[2]: メッセージボックスでの改行時に何を使いますか?
□投稿者/ ぶなっぷ (141回)-(2017/11/16(Thu) 08:56:32)
私の解釈では、GUI系は改行コードは自動変換だと思っています。
で、自動変換先は、CR+LF、これがWindows標準かなと。

ファイルに関しても、テキストモードで開けば、同じく自動変換かなと。
自動変換先は同じく、CR+LF

ファイルの場合に困るのは、自動変換の結果、
元の文字列のバイト長とファイル書き込み後のバイト長が異なってしまうこと。

それが問題になる場合は、バイナリモードで開いて、ちゃんとCR+LFを書き込む。
そんな感じでやっています。

引用返信 編集キー/
■85729 / inTopicNo.8)  Re[3]: メッセージボックスでの改行時に何を使いますか?
□投稿者/ 魔界の仮面弁士 (1468回)-(2017/11/16(Thu) 11:26:13)
No85726 (ぶなっぷ さん) に返信
> 私の解釈では、GUI系は改行コードは自動変換だと思っています。

VBA/VBS/VB/VB.NET の MsgBox 関数や InputBox 関数の仕様を再確認したところ、
》 引数 prompt に複数行を指定するには、改行する場所に
》 キャリッジ リターン (Chr(13))、ライン フィード (Chr(10))、または
》 キャリッジ リターンとライン フィードの組み合わせ (Chr(13) & Chr(10)) を
》 挿入してください。
と記載されていました。

GUI 上の見た目は一緒にしておいてやるから、バイナリーとして
重要な場合以外は違いを気にする必要は無いよ、という事なのかな…。


> で、自動変換先は、CR+LF、これがWindows標準かなと。

Windows 標準が「CR+LF」だとして、そのための自動変換が常に、
 LF → CR+LF
 CR → CR+LF
 CR+LF → CR+LF
であれば、個人的にはありがたかったのですけれども。(あるいはいっそ無変換!)


サポート技術情報の KB281670 (旧JP281670) や KB209791 (旧Q209791) で、
MsgBox 内の改行に vbCrLf を使うようにアナウンスされていることもあり、
私自身は元々、すべて CR+LF に統一する派でした。

ただ、先述のクリップボード転送時の影響があることは分かっていたので、
最近になって、ごく一部のメッセージボックスを LF に変更するよう修正してみました。
手間の割にメリットが薄いので、すべてリファクタしたわけでは無いですが。


改行といえば、Ruby の正規表現では、改行類のための構成要素として
\R というものがあるようですね。 (?>\x0D\x0A|[\x0A-\x0D\x{85}\x{2028}\x{2029}])
.NET の Regexp には見当たりませんでしたが。
引用返信 編集キー/
■85733 / inTopicNo.9)  Re[4]: メッセージボックスでの改行時に何を使いますか?
□投稿者/ furu (134回)-(2017/11/17(Fri) 10:22:54)
テキスト保存で
AccessやExcelはCR+LFですが
Wordでは4パターンすべて選べるんですね。

セル内の改行は

  Access CR+LF
  Excel LF
  Word CR+LF+LF または LF+CR+LF

でした。
Wordのは、なんでこうなるのって感じ。
引用返信 編集キー/
■85738 / inTopicNo.10)  Re[5]: メッセージボックスでの改行時に何を使いますか?
□投稿者/ misa (3回)-(2017/11/18(Sat) 18:34:56)
では、これで解決済みにしますね。

解決済み
引用返信 編集キー/
■85740 / inTopicNo.11)  Re[6]: メッセージボックスでの改行時に何を使いますか?
□投稿者/ Azulean (904回)-(2017/11/18(Sat) 19:52:17)
2017/11/18(Sat) 19:53:40 編集(投稿者)

No85738 (misa さん) に返信
> では、これで解決済みにしますね。

No85739 の誤爆ですかね…?
他の人が始めたスレッドを勝手に解決済みにしないようにしましょう。

-----

本筋としてはコードで書く場合はあまり気にせず、\n を置いていますね。
多くの場合は、メッセージ文言に Resources に詰め込んでいるので意識していませんでしたが…。
(まれに resx に改行コードが複数混入していてカオスなことになるが、誰がどのように作ったかの経緯を追えていないので有益な話はできないかな…)
引用返信 編集キー/
■85758 / inTopicNo.12)  Re[7]: メッセージボックスでの改行時に何を使いますか?
□投稿者/ 魔界の仮面弁士 (1472回)-(2017/11/21(Tue) 12:14:04)
No85726 (ぶなっぷ さん) に返信
> で、自動変換先は、CR+LF、これがWindows標準かなと。

インターネットの世界で見ると、
Content-Type: multipart/mixed;
で使われる boundary delimiter は CR+LF 固定ですね。
メッセージボックスとは無関係ですけど。


IE 向けサイトで使われていた TDC (Tabular Data Control) の場合、
既定の改行コードが LF に設定されていました。

'VBA
Dim TDC As Object
Set TDC = CreateObject("new:333C7BC4-460F-11D0-BC04-0080C7055A83")
Dim RowDelim As Variant
RowDelim = TDC.RowDelim 'LF



No85740 (Azulean さん) に返信
> ■No85738 (misa さん) に返信
>>では、これで解決済みにしますね。
>
> No85739 の誤爆ですかね…?
> 他の人が始めたスレッドを勝手に解決済みにしないようにしましょう。

ありがとうございます。
まぁ雑談なので、最後まで「解決」は付かないかも。


> 本筋としてはコードで書く場合はあまり気にせず、\n を置いていますね。

あくまで個人の感想ですが、
C# や C++ を多く使う人たちは LF (\n) を好み、
VB 系の人たちが CR+LF での改行を好む印象を持っています。


> 多くの場合は、メッセージ文言に Resources に詰め込んでいるので意識していませんでしたが…。
> (まれに resx に改行コードが複数混入していてカオスなことになるが、誰がどのように作ったかの経緯を追えていないので有益な話はできないかな…)

リソース等でのメッセージ文言は、自分は CrLf にすることが多いですが、
基本的にはさほど意識していないですね…ウチも時々混在しています。
引用返信 編集キー/
■85760 / inTopicNo.13)  Re[8]: メッセージボックスでの改行時に何を使いますか?
□投稿者/ ぶなっぷ (144回)-(2017/11/21(Tue) 13:35:01)
おそらくですが、C++/C#系の人たち(私自身を含む)は、
C++/C#の入門書がみんな'\n'で書かれているからだと思います。

それだけが原因で、ほとんどの人が何の疑問も持たず、
そういうものだと思っているんだと思います。

かくいう私自身も、
Windowsの標準が、CR+LFだとどこかの記事で読み、
C++の入門書では'\n'というものの実体がLFだと知り、
「え?一致していない」
と強烈に困惑したのを覚えています(笑)

引用返信 編集キー/
■85763 / inTopicNo.14)  Re[9]: メッセージボックスでの改行時に何を使いますか?
□投稿者/ furu (135回)-(2017/11/21(Tue) 17:36:47)
No85760 (ぶなっぷ さん) に返信
> おそらくですが、C++/C#系の人たち(私自身を含む)は、
> C++/C#の入門書がみんな'\n'で書かれているからだと思います。

BASICから入るとそんなことないんだろうけど
CがUNIX上でしか動いてなくて、C言語の本がUNIX前提だったから
'\n'で書かれているものばっかりだった気がする。

プログラム書法やソフトウェア作法の影響もあるのかな。

元々CR+LFだったものをカーニハンらがLFのみした?
簡潔にするの好きだから

引用返信 編集キー/
■85764 / inTopicNo.15)  Re[10]: メッセージボックスでの改行時に何を使いますか?
□投稿者/ shu (1068回)-(2017/11/21(Tue) 18:23:29)
CRとLFの元々の動作から考えると

CRだけだと行が動かない
LFだけだと行頭に戻らないので
CR+LFがよいのだと思う。

多分改行も1Byteで表せた方が処理しやすいのでLFだけの
処理系が生まれたものと思われます。
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ