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

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

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

Stringの配列がうまく作動しません

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

■100760 / inTopicNo.1)  Stringの配列がうまく作動しません
  
□投稿者/ あい (1回)-(2022/10/25(Tue) 00:23:38)

分類:[C#] 

Visual StudioでC#を用いてシステムの開発を行っています。
学校でプログラミングを習っただけの初心者です。

            for(int k=0; k < n; k++)
            {
                string[] list = { "医療分野の環境","患者満足と地域社会への貢献","医療の質の基本的考え方","医療の質・安全","医療安全の基本的考え方","顧客","製品・サービス","文書化と文書管理","文書の朱里","文書の体系","文書管理の方法","医療の質とモノの管理の関係","日常管理の実施方法","問題解決の手法"};
                string item = 実研修.M研修.Rows[k]["中項目名"].ToString();
                int m = Array.IndexOf(list, item)+1;
                Debug.WriteLine(item);
                Debug.WriteLine(k);
                Debug.WriteLine(m);
                Debug.WriteLine(Array.IndexOf(list, item));
                dgvQ項目.Rows[m].Cells[l].Value = "〇";
                l++;
            }

下記はコンソールに表示されたものです。


医療の質・安全
0
4
3
文書の朱里

1
0
-1
問題解決の手法

2
0
-1

簡単に言うと下記のような動作を行っています。
@実研修.M研修.Rows[k]["中項目名"].ToString();の部分でデータベースから中項目名を取得する
A配列から取得した中項目名のインデックス番号を取得する
Bインデックス番号をもとにシステムのデータグリッドビューの行番号を指定する

「医療の質・安全」という中項目名は配列からインデックス番号を取得できましたが、他の中項目名は取得できませんでした。
原因がわからないため添削をお願いしたいです。

引用返信 編集キー/
■100761 / inTopicNo.2)  Re[1]: Stringの配列がうまく作動しません
□投稿者/ Hongliang (1256回)-(2022/10/25(Tue) 02:47:46)
出力をそのままコピー&ペーストした結果だとすると、

> 医療の質・安全
> 0
> 4
> 3
> 文書の朱里
>
> 1
> 0
> -1
> 問題解決の手法
>
> 2
> 0
> -1

「文書の朱里」「問題解決の手法」とkの出力の間に1行隙間があります。「医療の質・安全」の方にはありません。
これから推測すると、「文書の朱里」「問題解決の手法」の末尾に何らかの改行文字が存在する可能性があります。
もしそうであるなら、Array.IndexOfは完全一致で検索するため、改行文字の有無で不一致となって見つからなくなっているということになります。
確認方法としては、文字列を1文字ずつその文字コードを表示させるとか。
foreach (char ch in item) { Debug.WriteLine((int)ch); }
引用返信 編集キー/
■100762 / inTopicNo.3)  Re[1]: Stringの配列がうまく作動しません
□投稿者/ KOZ (333回)-(2022/10/25(Tue) 07:38:34)
No100760 (あい さん) に返信
> Visual StudioでC#を用いてシステムの開発を行っています。

Visual Studio のデバッグ機能を活用しましょう。

「チュートリアル: Visual Studio を使用した C# のデバッグについて理解する」
https://learn.microsoft.com/ja-jp/visualstudio/get-started/csharp/tutorial-debugger?toc=%2Fvisualstudio%2Fdebugger%2Ftoc.json&view=vs-2022

引用返信 編集キー/
■100764 / inTopicNo.4)  Re[2]: Stringの配列がうまく作動しません
□投稿者/ あい (3回)-(2022/10/25(Tue) 09:02:34)
No100761 (Hongliang さん) に返信

> foreach (char ch in item) { Debug.WriteLine((int)ch); }

上記で確認したところ、ご指摘の通り文字列の末尾にLF(改行)とCR(復帰)が含まれておりました。

どのように解決できるのでしょうか?ご教示いただきたいです。

引用返信 編集キー/
■100765 / inTopicNo.5)  Re[3]: Stringの配列がうまく作動しません
□投稿者/ kiku (301回)-(2022/10/25(Tue) 09:30:17)
No100764 (あい さん) に返信
> ■No100761 (Hongliang さん) に返信
>>foreach (char ch in item) { Debug.WriteLine((int)ch); }
> 上記で確認したところ、ご指摘の通り文字列の末尾にLF(改行)とCR(復帰)が含まれておりました。
> どのように解決できるのでしょうか?ご教示いただきたいです。

下記のようにtrimを使って、改行などを削除してみてはどうでしょう。
https://dobon.net/vb/dotnet/string/trim.html
引用返信 編集キー/
■100767 / inTopicNo.6)  Re[3]: Stringの配列がうまく作動しません
□投稿者/ 魔界の仮面弁士 (3476回)-(2022/10/25(Tue) 10:00:09)
No100764 (あい さん) に返信
> 上記で確認したところ、ご指摘の通り文字列の末尾にLF(改行)とCR(復帰)が含まれておりました。
CR,LF ではなく、LF,CR が入っていた、という事でしょうか?
Windows の場合、一般的な改行は CR(\r),LF(\n) すなわち 0x0D,0x0A ですね。

また、Excel で生成された CSV の場合、「セル内改行」を \n で表し、
「レコード間の区切り」を \r\n または \r で表されることがあります。
このような場合は、セル内の改行もデータの一部ということになります。


> どのように解決できるのでしょうか?
「データ内の改行」もデータ内の一部なのか、それとも
データ内に改行は無い想定なのかで話が変わってきます。

もしも末尾改行が不要だというのであれば、混入していること自体が問題なのであり、
プログラム側では無く、処理対象の元データ側に問題があることを意味します。

その場合は実行前に、実研修.M研修 の中項目データ内に誤混入している
不要な改行を、プログラム実行前に取り除いておく必要があるでしょう。

あるいは元データには手を加えられない場合は、item を Debug.WriteLine する前に、
Replace メソッドを用いるなどして、不要な改行を取り除くようにします。


Replace の例:

(案1) Regex.Replace の場合
item = System.Text.RegularExpressions.Regex.Replace(item, @"\r|\n", "");
Debug.WriteLine(item);

(案2) String.Replace の場合
item = item.Replace("\r", "").Replace("\n", "")
Debug.WriteLine(item);


また、データ内の改行全てを削るのではなく、データ末尾の改行だけを削りたい場合は、
Trim あるいは TrimEnd メソッドを用いることができます。

(案3) String.TrimEnd の場合
item = item.TrimEnd('\r', '\n');
Debug.WriteLine(item);


なお、上記いずれの方法も、item の中身が null だった場合はエラーになります(item == "" の時は OK)。
もっとも今回のコードでは .ToString() の戻り値をセットしてあるので、
item が null になることは無さそうですけれどね。

引用返信 編集キー/
■100768 / inTopicNo.7)  Re[4]: Stringの配列がうまく作動しません
□投稿者/ ai (1回)-(2022/10/25(Tue) 10:59:49)
No100767 (魔界の仮面弁士 さん) に返信

> (案1) Regex.Replace の場合
> item = System.Text.RegularExpressions.Regex.Replace(item, @"\r|\n", "");
> Debug.WriteLine(item);

引用返信 編集キー/
■100769 / inTopicNo.8)  Re[5]: Stringの配列がうまく作動しません
□投稿者/ あい (4回)-(2022/10/25(Tue) 11:05:43)
No100767 (魔界の仮面弁士 さん) に返信
> 
>>(案1) Regex.Replace の場合
>>item = System.Text.RegularExpressions.Regex.Replace(item, @"\r|\n", "");
>>Debug.WriteLine(item);
> 

上記で解決できました!ありがとうございます。
続けてで申し訳ないのですが、中項目名にはコンボボックスから複数選択されたものが入るようになっています。その場合

医療の質・安全
医療安全の基本的考え方

というふうになっており、医療の質・安全/r/n医療安全の基本的考え方/r/nのようになってしまっています。

この場合、インデックス番号を複数取得し、 
              
        int m = Array.IndexOf(list, item)+1;
                dgvQ項目.Rows[m].Cells[l].Value = "〇";

この部分をその分ループさせることはできるのでしょうか?

引用返信 編集キー/
■100771 / inTopicNo.9)  Re[6]: Stringの配列がうまく作動しません
□投稿者/ 魔界の仮面弁士 (3477回)-(2022/10/25(Tue) 12:28:24)
No100769 (あい さん) に返信
> 医療の質・安全/r/n医療安全の基本的考え方/r/nのようになってしまっています。
"医療の質・安全\r\n医療の質・安全\r\n"
のように、同じコンテンツが重複指定されることはありますか?


> この場合、インデックス番号を複数取得し、
存在しないコンテンツが含まれる可能性があるのかも不明です。
"文書の朱里\r\n文書の首里城\r\n" などのように。

未知のコンテンツに対してエラーにするパターンもあれば、
-1 をインデックスとして返すというパターン、あるいは
存在自体を無視するといった選択肢もあろうかと思います。


さらに、インデックスの並びはどうあるべきか、という疑問もあります。
たとえば "医療の質の基本的考え方\r\n製品・サービス\r\n顧客\r\n" に対しては
インデックス順に {2, 5, 6}としたいのか、出現順に {2, 6, 5} と返すべきなのか。


string[] list = { "医療分野の環境", "患者満足と地域社会への貢献", "医療の質の基本的考え方", "医療の質・安全", "医療安全の基本的考え方", "顧客", "製品・サービス", "文書化と文書管理", "文書の朱里", "文書の体系", "文書管理の方法", "医療の質とモノの管理の関係", "日常管理の実施方法", "問題解決の手法" };

string searchText = "医療の質の基本的考え方\r\n製品・サービス\r\n顧客\r\n";

string[] m = searchText.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

// { 2, 6, 5 } となる
int[] indexArray1 = m.Select(s => Array.IndexOf(list, s)).Where(i => i >= 0).ToArray();

// { 2, 5, 6 } となる
int[] indexArray2 = list.Select((s, i) => m.Contains(s) ? i : -1).Where(i => i >= 0).ToArray();
引用返信 編集キー/
■100816 / inTopicNo.10)  Re[7]: Stringの配列がうまく作動しません
□投稿者/ あい (5回)-(2022/10/28(Fri) 23:02:34)
2022/10/28(Fri) 23:46:38 編集(投稿者)
2022/10/28(Fri) 23:15:09 編集(投稿者)

<pre><pre>■No100771 (魔界の仮面弁士 さん) に返信

> "医療の質・安全\r\n医療の質・安全\r\n"
> のように、同じコンテンツが重複指定されることはありますか?
同じコンテンツが重複されることはありません。

> 存在しないコンテンツが含まれる可能性があるのかも不明です。
> "文書の朱里\r\n文書の首里城\r\n" などのように。
存在しないコンテンツが含まれる可能性もありません。


> さらに、インデックスの並びはどうあるべきか、という疑問もあります。
> たとえば "医療の質の基本的考え方\r\n製品・サービス\r\n顧客\r\n" に対しては
> インデックス順に {2, 5, 6}としたいのか、出現順に {2, 6, 5} と返すべきなのか。
最終的に取得したインデックス番号を
                dgvQ項目.Rows[m].Cells[l].Value = "〇";
このmの部分にそれぞれ入れてデータグリッドビューの表中に〇印をつけたいと思っています。なので並び自体は関係ありません。
ただ、複数選択の場合は列は変わらずインデックス番号が行(Row)になるようにしたいです。イメージとしては

取得した番号それぞれを一つずつ入れるためにはどのようなループを回せばいいのでしょうか?

</pre></pre>

引用返信 編集キー/
■100817 / inTopicNo.11)  Re[8]: Stringの配列がうまく作動しません
□投稿者/ 魔界の仮面弁士 (3482回)-(2022/10/28(Fri) 23:34:34)
No100816 (あい さん) に返信
> 〇印をつけたいと思っています。

丸印なら、"〇" ではなく"○" を使うべきなのでは。


"〇"  // = "\u3007"; // Ideographic Number Zero (漢数字のゼロ)
"○"  // = "\u25CB"; // White Circle (記号の白丸)



> dgvQ項目.Rows[m].Cells[l].Value = "〇";

行列番号が明確な場合は、インデクサ指定による
 dgvQ項目[列, 行].Value = 値;
の構文を使うことができます。


また、DataGridView の DataSource プロパティに DataTable をバインドしている場合は、
dgvQ項目を直接操作するよりは、バインド元の DataTable 側を編集した方が望ましいです。
(DataTable や DataView は、値を元に該当行を検索する仕組みもあります)

.Cells[l] がバインド列で無い場合は、dgvQ項目側を操作するしか無いのですけれど。


> このmの部分にそれぞれ入れて
調べたインデックスをループ処理でそれぞれ渡して、丸印を書き込んでみてください。

引用返信 編集キー/
■100818 / inTopicNo.12)  Re[9]: Stringの配列がうまく作動しません
□投稿者/ あい (6回)-(2022/10/29(Sat) 00:14:37)
No100817 (魔界の仮面弁士 さん) に返信

無事に解決しました。
非常に分かりやすいご説明ありがとうございました。
解決済み
引用返信 編集キー/

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


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

このトピックに書きこむ