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

わんくま同盟

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

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

ツリー一括表示

string.IndexOfの結果について /暗黒魔界の王 佐藤 (23/09/28(Thu) 10:40) #102431
Re[1]: string.IndexOfの結果について /Hongliang (23/09/28(Thu) 10:59) #102432
│└ Re[2]: string.IndexOfの結果について /暗黒魔界の王 佐藤 (23/09/28(Thu) 11:24) #102435 解決済み
│  └ Re[3]: string.IndexOfの結果について /暗黒魔界の王 佐藤 (23/09/28(Thu) 11:56) #102437
│    └ Re[4]: string.IndexOfの結果について /魔界の仮面弁士 (23/09/28(Thu) 12:51) #102438
│      └ Re[5]: string.IndexOfの結果について /暗黒魔界の王 佐藤 (23/09/28(Thu) 14:15) #102439 解決済み
Re[1]: string.IndexOfの結果について /kiku (23/09/28(Thu) 11:24) #102434


親記事 / ▼[ 102432 ] ▼[ 102434 ]
■102431 / 親階層)  string.IndexOfの結果について
□投稿者/ 暗黒魔界の王 佐藤 (8回)-(2023/09/28(Thu) 10:40:13)

分類:[.NET 全般] 

連投失礼します。

下記のコードだとindexOfETXの値は3
******************************************************
string testString = "123" + "\u0003";
int indexOfETX = testString.IndexOf('\u0003');
******************************************************


下記のコードだとindexOfETXの値は0
******************************************************
string testString = "123" + "\u0003";
int indexOfETX = testString.IndexOf("\u0003");
******************************************************

検索対象として、文字を指定するか、文字列を指令するかの違いですが
文字列を指定した際に0になる理由が分かりません。
見つからないときは-1なので、
0ということは先頭に見つかっているということになりますが
なぜでしょうか?

[ □ Tree ] 返信 編集キー/

▲[ 102431 ] / ▼[ 102435 ]
■102432 / 1階層)  Re[1]: string.IndexOfの結果について
□投稿者/ Hongliang (1292回)-(2023/09/28(Thu) 10:59:38)
https://learn.microsoft.com/ja-jp/dotnet/api/system.string.indexof?view=net-7.0#system-string-indexof(system-string)
注釈にあるように、String.IndexOf(String)は現在のカルチャを使用して検索を行います。
そして同じく注釈にあるようにこの場合「無視できる文字」というのが存在しており、ETXはちょうどそれに該当します。
なので、"123".IndexOf("\u0003") ですら0を返します。

https://learn.microsoft.com/ja-jp/dotnet/api/system.string.indexof?view=net-7.0#system-string-indexof(system-char)
一方、String.IndexOf(Char)は序数検索、つまりUTF-16の符号単位での検索を行います。

引数に文字列を与えて序数検索するにはString.IndexOf(String, StringComparison)オーバーロードを使用し、第2引数にStringComparison.Ordinalを渡します。

https://learn.microsoft.com/ja-jp/dotnet/standard/base-types/best-practices-strings
文字列比較のベストプラクティスもご参照ください。
その中の一つに、IndexOfなどでは常にStringComparisonを明示することが挙げられています。
[ 親 102431 / □ Tree ] 返信 編集キー/

▲[ 102432 ] / ▼[ 102437 ]
■102435 / 2階層)  Re[2]: string.IndexOfの結果について
□投稿者/ 暗黒魔界の王 佐藤 (9回)-(2023/09/28(Thu) 11:24:52)
Hongliang 様

ありがとうございます。
助かりました。

今までずっと危険なプログラムを書いておりました。。。

下記にするとindexOfETXは無事3になりました。

string testString = "123" + "\u0003";
int indexOfETX = testString.IndexOf("\u0003", StringComparison.Ordinal); // ETX


String.Equals
String.Compare
String.IndexOf
String.StartsWith
も注意が必要なのですね。
解決済み
[ 親 102431 / □ Tree ] 返信 編集キー/

▲[ 102435 ] / ▼[ 102438 ]
■102437 / 3階層)  Re[3]: string.IndexOfの結果について
□投稿者/ 暗黒魔界の王 佐藤 (10回)-(2023/09/28(Thu) 11:56:20)
kiku 様

ご確認ありがとうございます。

今、いろいろ試しているのですが
こちらでもフレームワークによって違いが出ています。

VisualStudioの「対象のフレームワーク」の設定が
.NET Framework 4 client Profile
のとき、indexOfETXの値は3

.NET 6.0
のとき、indexOfETXの値は0
になります。


試したコード
string testString = "123" + "\u0003";
int indexOfETX = testString.IndexOf("\u0003");  // ETX


下記のコードすれば.NET 6.0でも結果は3になります。
string testString = "123" + "\u0003";
int indexOfETX = testString.IndexOf("\u0003", StringComparison.Ordinal);  // ETX



いまいちカルチャーとフレームワークの関係がわかりません。。。
下記のコードでカルチャを確認しようとすると、どちらの環境でも同じ結果になります。

CultureInfo currentCulture = CultureInfo.CurrentCulture;

string 現在のカルチャ= currentCulture.Name
string カルチャの表示名= currentCulture.DisplayName
string カルチャの言語= currentCulture.TwoLetterISOLanguageName

現在のカルチャ: ja-JP
カルチャの表示名: 日本語 (日本)
カルチャの言語: ja



[ 親 102431 / □ Tree ] 返信 編集キー/

▲[ 102437 ] / ▼[ 102439 ]
■102438 / 4階層)  Re[4]: string.IndexOfの結果について
□投稿者/ 魔界の仮面弁士 (3696回)-(2023/09/28(Thu) 12:51:28)
No102437 (暗黒魔界の王 佐藤 さん) に返信
> いまいちカルチャーとフレームワークの関係がわかりません。。。
> 下記のコードでカルチャを確認しようとすると、どちらの環境でも同じ結果になります。

.NET Framework では、Windows の各国語サポート(NLS)依存の実装でしたが、
マルチプラットフォーム対応のため、.NET 5 以降では既定で
ICU: International Components for Unicode のライブラリが採用されています。
(.NET 5 であっても、Win10 1903 未満で動作させる場合は NLS が使用されます)


この違いにより、StringComparison 等を指定しなかった場合の振る舞いが変更されています。

詳細は、 Hongliang さんが紹介された「.NET での文字列の比較に関するベスト プラクティス」の近くにあった
「.NET 5 以降で文字列を比較するときの動作の変更」をご覧ください。
https://learn.microsoft.com/ja-jp/dotnet/standard/base-types/string-comparison-net-5-plus?WT.mc_id=DT-MVP-8907
[ 親 102431 / □ Tree ] 返信 編集キー/

▲[ 102438 ] / 返信無し
■102439 / 5階層)  Re[5]: string.IndexOfの結果について
□投稿者/ 暗黒魔界の王 佐藤 (11回)-(2023/09/28(Thu) 14:15:31)
魔界の仮面弁士様

いつもお世話になっております。

教えていただいたWebページに
今回の悩みの理由がそのまま記載ありました。
ありがとうございました。

大変助かりました。
解決済み
[ 親 102431 / □ Tree ] 返信 編集キー/

▲[ 102431 ] / 返信無し
■102434 / 1階層)  Re[1]: string.IndexOfの結果について
□投稿者/ kiku (379回)-(2023/09/28(Thu) 11:24:13)
No102431 (暗黒魔界の王 佐藤 さん) に返信
> 連投失礼します。
>
> 下記のコードだとindexOfETXの値は3
> ******************************************************
> string testString = "123" + "\u0003";
> int indexOfETX = testString.IndexOf('\u0003');
> ******************************************************
>
>
> 下記のコードだとindexOfETXの値は0
> ******************************************************
> string testString = "123" + "\u0003";
> int indexOfETX = testString.IndexOf("\u0003");
> ******************************************************
>
> 検索対象として、文字を指定するか、文字列を指令するかの違いですが
> 文字列を指定した際に0になる理由が分かりません。
> 見つからないときは-1なので、
> 0ということは先頭に見つかっているということになりますが
> なぜでしょうか?

下記環境で動作させたところ、なぜかどちらも3になるなー。
ターゲットプレームワークにも依存しているみたい。

VisualStudio2022
.NETFrameWork4.8.1
WinForm
[ 親 102431 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -