質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

4回答

1742閲覧

C# String型の多次元配列の文字データを外部ファイルに保存したい

nishiyoshi0214

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

0クリップ

投稿2022/12/13 10:33

前提

プログラミング初心者です。
できれば細かく丁寧に解説していただけると非常に助かります。

C# でVisual Studio2022 で Windowsフォームアプリ作成しています。

string型の多次元配列(今回の例では30×12×31 要素)の文字列データを作成した外部ファイルに記録し、ソフト再起動時に配列に読み込みできるようにしたいです。
その方法を教えていただけると助かります。

現状、保存する部分のコードがかけていないのでソフトを落とせば配列に格納されたデータは消えてしまいます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2022/12/13 10:51

そういうコードを自力で考えて書くこともできますし、あらかじめ用意されているものでも様々な方法があります。例えば「C# シリアライズ」などと検索して学んでみてください。 [シリアル化 (C#)] https://learn.microsoft.com/ja-jp/dotnet/csharp/programming-guide/concepts/serialization/ 前提として、teratailは最初から手取り足取り細かく教えてもらうような「プログラミング何でも相談室」ではないです。
退会済みユーザー

退会済みユーザー

2022/12/14 23:29

質問者さん、回答したのでフィードバックを返してください。役に立った/立たなかったぐらいはすぐに返せるのでは? 役に立たなかったならどこがダメかを書くとより期待に近い回答が出てくるかも。
退会済みユーザー

退会済みユーザー

2022/12/29 01:01

質問者さん、無言ですがどうなりましたか? 進展があったら書いてください。ギブアップしたとかならクローズしてください。無言で放置は NG です。
guest

回答4

0

【訂正&追記】

下に「多次元配列は JSON 文字列にシリアライズできない」と書きましたが、それは System.Text.Json 名前空間のシリアライザ/デシリアライザの場合で Newtonsoft.Json のシリアライザ/デシリアライザは多次元配列にも対応していました。(TN8001 さんのコメントの通り)

Newtonsoft.Json を NuGet からインストールして以下のようにして使えます。

C#

1using System; 2using System.Windows.Forms; 3using Newtonsoft.Json; 4 5namespace WindowsFormsApp1 6{ 7 public partial class Form15 : Form 8 { 9 private string[,,] multidimensionalArray; // 多次元配列 10 private string[][][] jaggedArray; // ジャグ配列 11 private string json1; 12 private string json2; 13 14 public Form15() 15 { 16 InitializeComponent(); 17 } 18 19 // Load イベントで配列の初期化 20 private void Form15_Load(object sender, EventArgs e) 21 { 22 this.multidimensionalArray = new string[30, 12, 31]; 23 for (int i = 0; i < 30; i++) 24 { 25 for (int j = 0; j < 12; j++) 26 { 27 for (int k = 0; k < 31; k++) 28 { 29 this.multidimensionalArray[i, j, k] = 30 $"elem-{i}-{j}-{k}"; 31 } 32 } 33 } 34 35 this.jaggedArray = new string[30][][]; 36 for (int i = 0; i < 30; i++) 37 { 38 this.jaggedArray[i] = new string[12][]; 39 for (int j = 0; j < 12; j++) 40 { 41 this.jaggedArray[i][j] = new string[31]; 42 for (int k = 0; k < 31; k++) 43 { 44 this.jaggedArray[i][j][k] = 45 $"elem-{i}-{j}-{k}"; 46 } 47 } 48 } 49 } 50 51 // Newtonsoft.Json でシリアライズ 52 private void Serialize_Click(object sender, EventArgs e) 53 { 54 // 多次元配列を JSON 文字列にシリアライズ 55 this.json1 = JsonConvert.SerializeObject(this.multidimensionalArray); 56 57 // ジャグ配列を JSON 文字列にシリアライズ 58 this.json2 = JsonConvert.SerializeObject(this.jaggedArray); 59 60 // comp は true になる 61 bool comp = this.json1 == this.json2; 62 } 63 64 // Newtonsoft.Json でデシリアライズ 65 private void Deserialize_Click(object sender, EventArgs e) 66 { 67 // JSON 文字列を多次元配列にデシリアライズ 68 var array1 = JsonConvert.DeserializeObject<string[,,]>(this.json1); 69 70 // JSON 文字列をジャグ配列にデシリアライズ 71 var array2 = JsonConvert.DeserializeObject<string[][][]>(this.json2); 72 } 73 } 74}

配列を JSON 文字列にシリアライズしてファイルに保存し、使うときはファイルから JSON 文字列を取得して元の配列にデシリアライズして使うようにしてはいかがですか?

ただし、多次元配列は JSON 文字列にシリアライズできないので、ジャグ配列を使ってください。

ジャグ配列 (C# プログラミング ガイド)
https://learn.microsoft.com/ja-jp/dotnet/csharp/programming-guide/arrays/jagged-arrays

.NET Framework 4.7.2 以降のバージョンであれば、System.Text.Json 名前空間のシリアライザ/デシリアライザを利用できますので、NuGet から System.Text.Json をインストールしてください。.NET Framework 4.7.2 より前のアプリの場合は Newtonsoft.Json を使ってください。

.NET 内で JSON のシリアル化と逆シリアル化を行う方法
https://learn.microsoft.com/ja-jp/dotnet/standard/serialization/system-text-json/how-to?pivots=dotnet-7-0

サンプルコードを以下に載せておきます。

C#

1using System; 2using System.Windows.Forms; 3using System.Text.Json; 4 5namespace WindowsFormsApp1 6{ 7 public partial class Form15 : Form 8 { 9 private string[,,] multidimensionalArray; // 多次元配列 10 private string[][][] jaggedArray; // ジャグ配列 11 private string json; 12 13 public Form15() 14 { 15 InitializeComponent(); 16 } 17 18 // Load イベントで配列の初期化 19 private void Form15_Load(object sender, EventArgs e) 20 { 21 this.multidimensionalArray = new string[30, 12, 31]; 22 for (int i = 0; i < 30; i++) 23 { 24 for (int j = 0; j < 12; j++) 25 { 26 for (int k = 0; k < 31; k++) 27 { 28 this.multidimensionalArray[i, j, k] = $"elem-{i}-{j}-{k}"; 29 } 30 } 31 } 32 33 this.jaggedArray = new string[30][][]; 34 for (int i = 0; i < 30; i++) 35 { 36 this.jaggedArray[i] = new string[12][]; 37 for (int j = 0; j < 12; j++) 38 { 39 this.jaggedArray[i][j] = new string[31]; 40 for (int k = 0; k < 31; k++) 41 { 42 this.jaggedArray[i][j][k] = $"elem-{i}-{j}-{k}"; 43 } 44 } 45 } 46 } 47 48 // 配列を JSON 文字列にシリアライズ 49 private void Serialize_Click(object sender, EventArgs e) 50 { 51 // 多次元配列の JSON シリアル化はサポートされてない。以下の例がスローされる 52 // System.NotSupportedException The type 'System.String[,,]' is not supported. 53 //string json = JsonSerializer.Serialize(this.multidimensionalArray); 54 55 this.json = JsonSerializer.Serialize(this.jaggedArray); 56 } 57 58 // JSON 文字列からジャグ配列にデシリアライズ 59 private void Deserialize_Click(object sender, EventArgs e) 60 { 61 var array = JsonSerializer.Deserialize<string[][][]>(this.json); 62 } 63 } 64}

シリアライズ/デシリアライズの結果は以下のようになります。

イメージ説明

投稿2022/12/14 03:24

編集2022/12/14 06:07
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TN8001

2022/12/14 11:30 編集

Newtonsoft.Json(Json.NET)は、多次元配列にも対応しているようです(jsonはジャグ配列のそれなのですが) [Json.NET vs .NET Serializers](https://www.newtonsoft.com/json/help/html/jsonnetvsdotnetserializers.htm#:~:text=Serializes%20and%20deserializes%20multidimensional%20arrays) [James Newton-King - Json.NET 4.5 Release 8 – Multidimensional Array Support, Unicode Improvements](http://james.newtonking.com/archive/2012/08/06/json-net-4-5-release-8-multidimensional-array-support-unicode-improvements)
退会済みユーザー

退会済みユーザー

2022/12/14 05:46

> Newtonsoft.Jsonは、多次元配列にも対応しているようです(jsonはジャグ配列のそれなのですが) そうですね、上のコードの multidimensionalArray を Newtonfost.Json のシリアライザ/デシリアライザを使って確認してみました。回答を訂正しておきます。
guest

0

私自身 C# はあまり触れた経験が無いため,超初心者目線での話になりますが…

  • 自分で必要十分と思える「てきとーフォーマット」を定めて読み書きするのが(学習コスト的な意味で/ブラックボックスが少ない的な意味で気分的に?)楽なんじゃないかな?
  • とりあえず最初は1次元のデータあたりで,軽く練習してみては?

…とか思います.

例えば,以下のコードは 初心者丸出し 且つ いろいろといい加減な所が多い ですが,ファイル保存/読込の最初の練習としては,こんな感じのところからやってみるのが良いのではないかな? みたいな.

C#

1//コンソールアプリで書いた. 2//読み書き対象のデータは1次元配列. 3//ググったら StreamReader, StreamWriter というやつでやれるぞ,って感じの話が見つかったのでこいつらを使用した. 4 5class Program 6{ 7 /// <summary> 8 /// Dataの内容をファイルに保存する. 9 /// <remarks> 10 /// ※とりあえず話を簡単にするために,各stringは改行を含まない想定. 11 /// </remarks> 12 /// </summary> 13 /// <param name="FilePath">保存ファイルパス名</param> 14 /// <param name="Data">保存対象データ</param> 15 /// <returns>成否</returns> 16 static bool Save( string FilePath, string[] Data ) 17 { 18 try 19 { 20 using( var SW = new StreamWriter( FilePath ) ) 21 { 22 //最初の行にはデータ数を出力 23 SW.WriteLine( Data.Length.ToString() ); 24 //以降は1行に1データをダブルクォートで囲んだ状態で出力 25 foreach( var s in Data ){ SW.WriteLine( "\"" + s + "\"" ); } 26 } 27 return true; 28 } 29 catch( Exception ex ) //←ココを真面目に書くのは面倒そうだなぁ 30 {//ココでいきなりコンソールにメッセージ吐いちゃう 31 Console.WriteLine( "In Save() : " + ex.Message ); 32 return false; 33 } 34 } 35 36 /// <summary> 37 /// Save()で保存したファイルを読込む. 38 /// </summary> 39 /// <param name="FilePath"></param> 40 /// <returns> 41 /// 結果データ. 42 /// ただしエラー時にはnullを返す. 43 /// </returns> 44 static string[] Load( string FilePath ) 45 { 46 try 47 { 48 using( var SR = new StreamReader( FilePath ) ) 49 { 50 int nStrs = int.Parse( SR.ReadLine() ); 51 if( nStrs <= 0 ) 52 { throw new Exception( "Invalid Data Count : " + nStrs.ToString() ); } 53 54 var Data = new string[nStrs]; 55 for( int i=0; i<nStrs; ++i ) 56 { 57 string LineStr = SR.ReadLine().Trim(); 58 if( !LineStr.StartsWith( "\"" ) || !LineStr.EndsWith( "\"" ) ) 59 { throw new Exception( "FormatErr : " + LineStr ); } 60 61 Data[i] = LineStr.Trim( '\"' ); 62 } 63 return Data; 64 } 65 } 66 catch( Exception ex ) 67 { 68 Console.WriteLine( "In Load() : " + ex.Message ); 69 return null; 70 } 71 } 72 73 //Main 74 static void Main() 75 {//ファイルに保存して→それを即読込む,というのをやってみる 76 string FilePath = "Test.txt"; 77 78 {//Test Save() 79 var Strs = new string[] 80 { 81 "Hello World", 82 " Cat ", 83 " Kitten " 84 }; 85 86 if( !Save( FilePath, Strs ) )return; 87 } 88 89 {//Test Load() 90 var Strs = Load( FilePath ); 91 if( Strs != null ) 92 { 93 Console.WriteLine( Strs.Length.ToString() + " strs :" ); 94 foreach( var s in Strs ){ Console.WriteLine( "[" + s + "]" ); } 95 } 96 } 97 98 Console.Read(); 99 } 100}

投稿2022/12/14 01:57

編集2022/12/14 01:58
fana

総合スコア11660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2022/12/14 02:04

例えば,このしょぼいコードによるファイル形式を3次元な配列を扱う形に変更するとしたら, ファイルの最初の行に 30 12 31 って3つのサイズを書くとか,あるいは3行使って 30 12 31 と書くとかいうことにし, 以降は自分で定めた順番で 30×12×31 個の文字列を並べる,みたいな?
guest

0

C# 設定値保存、なんかでぐぐると、いろいろ解説が出てきます

投稿2022/12/13 23:24

y_waiwai

総合スコア87782

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

JSONで記録しておくのはいかがでしょうか

投稿2022/12/13 10:35

yuma.inaura

総合スコア1453

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2022/12/13 10:43

具体的にどうするのか書きましょう。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問