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

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

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

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

4657閲覧

c# 配列をグローバルに使いたい

kyudou-syounen

総合スコア3

C#

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

1グッド

0クリップ

投稿2021/12/21 12:04

編集2021/12/24 11:27

前提・実現したいこと

c#を勉強し始めて1か月もたっていない超初心者です。
現在、visual studio2019でWindowsフォームアプリケーションを用いてアプリを作成しています。アプリは、ボタン2を押すとcsvデータを読み取り配列に格納する。ボタン1を押すとその配列の要素を計算してテキストボックスに表示するというものです。

https://teratail.com/questions/38442
こちらで載っている質問を参考に作成していたのですが、
数字であるcsvデータをカンマ区切りで分割して配列に格納する方法とその配列をボタン1のコードでも使えるようにする方法がわかりません。
c#にグローバル変数がないことは色々調べていくうちにわかりました。
いかにコードを載せさせていただきます。
ご助言いただけると幸いです。
よろしくお願いいたします。

読み込みたいcsvデータ例
13
14
34
45
45
70
46
113
133

上記のように数値のみがデータとして出てくるものです。
これらのデータを読み込むことで配列一つ一つの要素を用いて計算できる。

c#

1using System; 2using System.Collections.Generic; 3using System.ComponentModel; 4using System.Data; 5using System.Drawing; 6using System.Linq; 7using System.Text; 8using System.Threading.Tasks; 9using System.Windows.Forms; 10 11namespace math-aplication 12{ 13 public partial class Form1 : Form 14 { 15 public Form1() 16 { 17 InitializeComponent(); 18 19 20 } 21 22 //★ 23 24public void button2_Click(object sender, EventArgs e) 25 { 26 ReadCsv(); 27 } 28 29 public static List<string[]> stArrayData = new List<string[]>(); 30 static void ReadCsv() 31 { 32 33 void ReadCsv() 34 { 35 try 36 { 37 // csvファイルを開く 38 System.IO.DirectoryInfo dirPath = 39 new System.IO.DirectoryInfo(@""); 40 System.IO.FileInfo[] files = 41 dirPath.GetFiles("", System.IO.SearchOption.AllDirectories); 42 43 // 指定フォルダからCSVを取得し、配列に格納する。 44 foreach (System.IO.FileInfo filePath in files) 45 { 46 using (var readCsv = new System.IO.StreamReader(filePath.FullName)) 47 { 48 //ヘッダを読み捨てる。 49 readCsv.ReadLine(); 50 // ストリームの末尾まで繰り返す 51 while (!readCsv.EndOfStream) 52 { 53 // ファイルから一行読み込む 54 var line = readCsv.ReadLine(); 55 //ここの部分で数字の配列なのでこのままだといけませんでした。 56 string[] record = line.Split(','); 57 stArrayData.Add(record); 58 } 59 } 60 } 61 } 62 finally 63 { 64 textBox1.Text = "読み取ってへんで!!"; 65 }; 66 67 } 68 69 } 70 71public void button1_Click(object sender, EventArgs e) 72 { 73 74 75 76 double l = 0; 77 78 for (int i = 0; i < B.Length; ++i) 79 { 80 l += record[i]; 81 } 82 83 84 85 this.Invoke(new MethodInvoker(() => textBox1.Text = Convert.ToString(l))); 86 } 87 88 89 } 90 91 92}

試したこと

★マークの部分で"record"として配列を宣言したのですがボタン1のほうでは反映されていませんでした。

初めての利用のため、質問内容がわかりにくいかもしれません。
ご助言いただけると幸いです。
よろしくお願いいたします。

TN8001👍を押しています

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

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

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

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

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

dodox86

2021/12/21 12:42

> ★マークの部分で"record"として配列を宣言したのですがボタン1のほうでは反映されていませんでした。 反映されないも何も、コンパイルエラーで実行ファイルは作成されず、したがってプログラムは実行できないはずですが。実行できないことを「反映されない」と言っていませんか。使えそうなコードをただコピー&ペーストするのではなく、一行一行ちゃんと理解しましょう。
退会済みユーザー

退会済みユーザー

2021/12/21 13:21 編集

> //ここの部分で数字の配列なのでこのままだといけませんでした。 「いけません」とはどういうことですか? 何がどのように行けたらいいのですか? > c#にグローバル変数がないことは色々調べていくうちにわかりました。 あなたの言う「グローバル変数」というのは何ですか?
kyudou-syounen

2021/12/22 03:09

dodox86様、コメントありがとうございます。 私自身の知識不足によりプログラミングの基本的な言葉の意味・使い方を間違えてしまいました。 これからしっかりと勉強していこうと思います。
kyudou-syounen

2021/12/22 03:16

SurferOnWww様、コメントありがとうございます。 >「いけません」とはどういうことですか? 何がどのように行けたらいいのですか? 参考にさせていただいたものが文字列のデータの読み込みであったため、私が読み込みたい数値のみのデータに適するようにコードを変更しようとしたのですが、コードにエラーが出てしまったので今回「いけません」というような表現をしました。数値のみのデータをカンマ区切りで分割して配列に格納したいと考えています。 > c#にグローバル変数がないことは色々調べていくうちにわかりました。 私のイメージなのですが、どの処理にも共有して使えるようなものと考えています。
退会済みユーザー

退会済みユーザー

2021/12/22 03:41

> コードにエラーが出てしまったので今回「いけません」というような表現をしました。 button2_Click では行けてて(エラーは出なくて)、button1_Click の l += record[i]; でエラーになるのが「いけません」ということではないのですか? > 私のイメージなのですが、どの処理にも共有して使えるようなものと考えています。 C# の変数のスコープについて勉強しましょう。もう一つ、型についても勉強して、l += record[i]; ということはできなくてパースが必要ということも学びましょう。
guest

回答2

0

ベストアンサー

参考の質問は複数のcsvを読む作りですが、一度に複数読みたいのでしょうか?

とりあえず1ファイルの読み込みで作りました。
ファイル全部読むのにStreamReaderは冗長なだけなので、もっと簡単な方法を使います。

Form1にはbutton1button2label1があるとします。
それぞれのボタンにはクリックイベントを付けます。

csvの例がないので適当にでっち上げましたが、配列のインデックス等は調整してください。

注意)エラー処理が一切ありません。
ヘッダー以外にintにならない文字や途中の空行・データが足らない等があると、当然落ちます^^;

cs

1using System; 2using System.Collections.Generic; 3using System.Data; 4using System.IO; 5using System.Linq; 6using System.Windows.Forms; 7 8namespace Questions374940 9{ 10 public partial class Form1 : Form 11 { 12 // 「別クラスからどうのこうの」ということがなければ、別にstaticにすることもない 13 // フィールド(メンバ変数)は、button1_Clickからもbutton2_Clickからもアクセスできます 14 private List<int[]> csvData = new List<int[]>(); 15 16 public Form1() 17 { 18 InitializeComponent(); 19 DummyData(); // test.csv作成 20 } 21 22 private void DummyData() 23 { 24 // 内容に特に意味はない(例がなかったので適当) 25 string s = "No,Prime,Fibonacci\n1,2,0\n2,3,1\n3,5,1\n4,7,2\n5,11,3\n6,13,5\n7,17,8\n8,19,13\n9,23,21\n10,29,34\n"; 26 27 // ファイルに書き出し 28 File.WriteAllText("test.csv", s); 29 } 30 31 // 読み込みボタン 32 private void button1_Click(object sender, EventArgs e) 33 { 34 // ファイルを開くダイアログ 35 OpenFileDialog openFileDialog = new OpenFileDialog 36 { 37 Filter = "CSVファイル(*.csv)|*.csv", 38 }; 39 40 // ファイルを選ばなかったら処理終わり 41 if (openFileDialog.ShowDialog() != DialogResult.OK) return; 42 43 // 選んだファイルのパス 44 string filePath = openFileDialog.FileName; 45 46 // ファイルを1行ずつ読む(けど最初の行はとばす 47 foreach (string line in File.ReadLines(filePath).Skip(1)) 48 { 49 // 1行をカンマで分割 50 string[] strArray = line.Split(','); 51 52 // string[]からint[]に変換 53 // [C# - C# string配列 を int配列 に変換したい(スッキリとしたコードで)|teratail](https://teratail.com/questions/48472) 54 int[] intArray = strArray.Select(int.Parse).ToArray(); 55 56 // csvDataに追加 57 csvData.Add(intArray); 58 } 59 } 60 61 // 計算ボタン 62 private void button2_Click(object sender, EventArgs e) 63 { 64 // 各行に No,Prime,Fibonacci とある前提 65 66 int sumPrime = 0; // Primeの合計 67 int sumFibonacci = 0; // Fibonacciの合計 68 69 // csvDataを1件ずつループ 70 foreach (int[] intArray in csvData) 71 { 72 sumPrime += intArray[1]; 73 sumFibonacci += intArray[2]; 74 } 75 76 // 件数・合計の表示 77 label1.Text = $"{csvData.Count} 件\nPrime合計: {sumPrime}\nFibonacci合計: {sumFibonacci}"; 78 } 79 } 80}

説明多めにしたつもりですが、わからない点があればコメントしてください。


追記 各行数字ひとつ版

cs

1using System; 2using System.Data; 3using System.IO; 4using System.Linq; 5using System.Windows.Forms; 6 7namespace Questions374940 8{ 9 public partial class Form1 : Form 10 { 11 // button2を先に押されるとエラーになるので無駄だが0個で作っとくw 12 private int[] intArray = new int[0]; 13 14 public Form1() 15 { 16 InitializeComponent(); 17 DummyData(); 18 } 19 20 private void DummyData() 21 { 22 string s = "13\n14\n34\n45\n45\n70\n46\n113\n133\n"; 23 File.WriteAllText("test.csv", s); 24 } 25 26 private void button1_Click(object sender, EventArgs e) 27 { 28 OpenFileDialog openFileDialog = new OpenFileDialog 29 { 30 Filter = "CSVファイル(*.csv)|*.csv", 31 }; 32 if (openFileDialog.ShowDialog() != DialogResult.OK) return; 33 34 string filePath = openFileDialog.FileName; 35 36 // ファイルを全部読む(最後に改行があるとエラーになるので取っておく) 37 string text = File.ReadAllText(filePath).Trim(); 38 39 // 空白文字(スペースや改行)で分割 40 string[] strArray = text.Split(); 41 42 // string[]からint[]に変換 43 intArray = strArray.Select(int.Parse).ToArray(); 44 } 45 46 private void button2_Click(object sender, EventArgs e) 47 { 48 int sum = Hoge.Sum(intArray); 49 label1.Text = $"{intArray.Length} 件\n合計: {sum}"; 50 } 51 52 } 53 54 class Hoge 55 { 56 public static int Sum(int[] intArray) 57 { 58 int sum = 0; 59 foreach (int i in intArray) 60 { 61 sum += i; 62 } 63 return sum; 64 } 65 } 66}

投稿2021/12/21 15:58

編集2023/07/29 13:08
TN8001

総合スコア9862

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

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

kyudou-syounen

2021/12/22 07:30

TN8001様、回答していただきありがとうございます。 コードを拝見させていただいて気になった部分がありましたので、お聞きさせていただいてよろしいでしょうか? 読み取ったcsvデータを一度”int[] intArray”の配列に格納しているように思うのですが、この配列をボタン2の計算に利用することはできないのでしょうか? また、TN8001様に書いていただいたコードのにおいてListとしてある"csvData"を配列に変換するコードは上記にどの部分に書けば良いのでしょうか? 配列に変換するコードは以下のものを利用しようと考えています。 int[] array; array = csvData.ToArray(); できれば計算には配列を用いたいと考えております。 度々の質問になってしまい申し訳ございません。 お手数ですがご教授のほどよろしくお願い致します。
TN8001

2021/12/22 07:58

> この配列をボタン2の計算に利用することはできないのでしょうか? 1行には(ヘッダーを除いて)数字が何個かあるわけですよね? 私の例であれば 1,2,0 2,3,1 ・・・・・ となっています。 それをintの配列に変えますよね? [1,2,0] [2,3,1] ・・・・・ そのintの配列をさらにまとめたものが、csvDataです。 csvData.Add(intArray); と、どんどん追加していっています。 使うときは foreach (int[] intArray in csvData) とすると追加した順に(つまりcsvの上から順に)取り出せます。 どのような計算がしたいのかはわかりませんが、回答ではそれぞれの列の合計を計算しています。 > Listとしてある"csvData"を配列に変換するコードは上記にどの部分に書けば良いのでしょうか? 別にListを使ってはダメな縛りがあるわけじゃないんですよね? List<string[]> stArrayData と使っておられますし。 csvDataはint配列のリストでして、2次元配列のようになっています。 なので int[] array = csvData.ToArray(); とはできません。 やるなら int[][] array ですが、kyudou-syounenさんが欲しいデータは(上にも書きましたが)もうできているのです。 foreach (int[] intArray in csvData) ここの intArray が Addしたときの intArray と同じものです。 2次元になってしまっているから難しく感じているのでしょうか?(単にエクセルみたいな表形式ってだけですが) 読み込み時は List<string> にしておいて、計算時にSplitやint.Parseしたほうがいいでしょうか?
kyudou-syounen

2021/12/22 16:08 編集

TN8001様、丁寧な回答に加え解説までしていただきありがとうございます。 私が読み込みたいcsvデータは数値のみの一次元配列となっております。例を挙げずに質問してしまい申し訳ございません。 ”int[] intArray”の件、解説を読んで理解することができました。もうこのlistを使って計算できるのですね。 実は、配列の要素全てを一つずつ計算させるようなコードを別のプログラミングで作っているのでそのコードと組み合わせたいなと考えており、配列での計算を希望していました。配列の計算では、for文を用いて全ての要素をLengthで計算させていたのですが、listを使う場合はforeachを用いてコードを書けばよろしいのでしょうか? > 読み込み時は List<string> にしておいて、計算時にSplitやint.Parseしたほうがいいでしょうか? 初心者ゆえ、間違っていることを言っているかもしれないのですが、上記のような処理を行うことでTN8001様が書いてくださったコードとはどのような違いがあるのでしょうか? 私の中では、int型などに変換することができるという点で同じように考えています。 回答していただけるとありがたいです。 よろしくお願い致します。
TN8001

2021/12/23 02:38

> 私が読み込みたいcsvデータは数値のみの一次元配列となっております。 1次元ということは各行に数値がひとつしかないって意味ですか? つまりカンマがいっこもないということ?(まあなくてもcsvではあるでしょうが^^; あるいは逆にヘッダーとデータの2行しかないってことですか?? > 例を挙げずに質問してしまい申し訳ございません。 別に謝る必要はありませんが、今からでも質問に追記してください。 読み込みたいcsvの例と、それを読んだらどんな結果を期待するのかの2点です。 > 実は、配列の要素全てを一つずつ計算させるようなコード あっもしかして、私の回答でいえばPrimeの配列・Fibonacciの配列と縦の並びでint[]が欲しいという意味でしょうか? > 別のプログラミングで作っているのでそのコードと組み合わせたい これも割とよくある質問なんですが、もし別のコンソールプログラム class Program {  static void Main(string[] args)  {   // 何か処理  } } のようなもののことを言っているのであれば、それは別のexeになってしまいForm1からは非常に扱いづらいです。 Form1とは別のクラスになっているだけで、同じexeになるんだったら問題ないです。 > for文を用いて全ての要素をLengthで計算させていたのですが、listを使う場合はforeachを用いてコードを書けばよろしいのでしょうか? 配列もリストもfor・foreach両方可能です。 入門書ではいまだにfor文が先に出てくることが多いですが、個人的にはレガシーコード(時代遅れの古いコード)だと思っています(もちろんforがいい場面もあるでしょうが、全列挙するならforeach) // 配列をforで合計 int[] array = { 1, 2, 3 }; int sum = 0; for (int i = 0; i < array.Length; i++) {  sum += array[i]; } // 配列をforeachで合計 int[] array = { 1, 2, 3 }; int sum = 0; foreach (int value in array) {  sum += value; } // 配列をLinqで合計 int[] array = { 1, 2, 3 }; int sum = array.Sum(); // リストをforで合計 List<int> list = new List<int> { 1, 2, 3 }; int sum = 0; for (int i = 0; i < list.Count; i++) {  sum += list[i]; } // リストをforeachで合計 List<int> list = new List<int> { 1, 2, 3 }; int sum = 0; foreach (int value in list) { sum += value; } // リストをLinqで合計 List<int> list = new List<int> { 1, 2, 3 }; int sum = list.Sum(); 全部同じ意味です。 > どのような違いがあるのでしょうか? 本質的には何も変わりません。単にいつやるかどうやるかってだけの話です。 しかし2次元配列が苦手な方もいるので、2次元にならない方法を提案しただけです(わたしもたまに縦と横どっちがどっちだっけ?ってなったりしますw
kyudou-syounen

2021/12/24 11:48

>あっもしかして、私の回答でいえばPrimeの配列・Fibonacciの配列と縦の並びでint[]が欲しいという意味でしょうか? そうですね。私の場合ですと、1次元配列なのでシンプルに読み込んだ数値が並ぶint[]が欲しいということになります。 今は、配列の計算において隣り合う要素の差を出すという方法が面白いなと思ったので”var A = new double[Val.Length-1];”をListで再現できないかを試していこうと思っています。一応以下にリンクを張らせていただきます。 https://teratail.com/questions/372755 >同じexeになるんだったら問題ないです。 私の場合は、同じexeになっていると思いますので、大丈夫だと思います。 今のところエラーも出ていないので笑 >全部同じ意味です。 配列の計算のコードもおぼつかない私に、for,foreachの書き方を丁寧に解説していただきありがとうございます。これから勉強していこうと思います。 >本質的には何も変わりません。 そうなんですね。2次元配列で今回のような処理を行いたくなった際に参考にさせていただきます。 何度もコメントの場の質問の答えていただきありがとうございました。 TN8001様の回答をベストアンサーにさせていただきます。
TN8001

2021/12/24 12:09

各行数字ひとつ版も追記しました。 List<int[]> csvDataから任意の列を配列にするほうが汎用的だとは思いますが、ちょっと難しくなるかもしれないので単純な方法にさせていただきました。
guest

0

それで行けるはずですが、反映されてないとはどのように確認されたんでしょうか

投稿2021/12/21 12:08

y_waiwai

総合スコア88042

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

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

kyudou-syounen

2021/12/21 12:25

回答ありがとうございます。 csvデータが数値のみの物なので、"int[]record = new int {10}"と宣言したところ、ボタン1の方の"record"にエラーがついていました。これは、ボタン2ではstring型で定義しているのに★のところに宣言したのはint型だからなのでしょうか?初心者なので基礎的なことを聞いてしまっているかもしれません。 またそうである場合、数値のcsvデータをカンマ区切りで分割して配列に格納する方法を教えていただきたいです。 よろしくお願い致します。
dodox86

2021/12/21 12:43

コンパイルエラーで全然行けませんよ。
退会済みユーザー

退会済みユーザー

2021/12/21 13:15

「行けるはず」とのことですが、どこにどのように行けるのですか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問