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

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

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

C++/CLI

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

■84631 / inTopicNo.1)  C++/CLI
  
□投稿者/ アルマジロ (1回)-(2017/07/24(Mon) 12:07:33)

分類:[.NET 全般] 

C++/CLIの質問です。
フォーム上のボタンを押して、数値データが記載されているtextファイルやdatファイルを読み込むと、
その数値データを配列 DATA[i] に数値として格納するプログラムを作成しています。(最終的にはグラフにしたい、、、)

Stringデータとして、TableData[i]に格納するところまではいったのですが、

TableData[i]の文字配列を冒頭で宣言した DATA[i] に数値配列として格納する方法を教えて頂けませんでしょうか?

宜しくお願い致します。


public: array<double,1>^DATA = gcnew array<double,1>(i);


private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {

openFileDialog1->Filter = "DataFile(*.dat)|*.dat";
if (openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::Cancel) return;

StreamReader ^ reader = gcnew StreamReader(openFileDialog1->FileName, System::Text::Encoding::GetEncoding("shift-jis"));

String ^Data = reader->ReadToEnd();

reader->Close();

array<String^>^LineData = Data->Split(gcnew array<String^>{"\r", "\r", "\r"}, StringSplitOptions::RemoveEmptyEntries);
array<array<String^>^>^ TableData = gcnew array<array<String^>^>(LineData->Length);


for (int i = 0; i < LineData->Length; i++) {
TableData[i] = LineData[i]->Split(',');

}
引用返信 編集キー/
■84632 / inTopicNo.2)  Re[1]: C++/CLI
□投稿者/ WebSurfer (1270回)-(2017/07/24(Mon) 12:26:05)
No84631 (アルマジロ さん) に返信

> TableData[i]の文字配列を冒頭で宣言した DATA[i] に数値配列として格納する方法を教えて頂けませんでしょうか?

一つ一つパースしながら代入していくといったプリミティブな方法ではダメなんでしょうか?

引用返信 編集キー/
■84633 / inTopicNo.3)  Re[2]: C++/CLI
□投稿者/ アルマジロ (2回)-(2017/07/24(Mon) 12:42:08)
No84632 (WebSurfer さん) に返信
> ■No84631 (アルマジロ さん) に返信
>
>>TableData[i]の文字配列を冒頭で宣言した DATA[i] に数値配列として格納する方法を教えて頂けませんでしょうか?
>
> 一つ一つパースしながら代入していくといったプリミティブな方法ではダメなんでしょうか?
>

返信有難う御座います。

こういった感じでしょうか?

for (int i = 0; i < LineData->Length; i++) {
TableData[i] = LineData[i]->Split(',');

float DATA[i] = float::Parse(TableData[i]);

}



引用返信 編集キー/
■84638 / inTopicNo.4)  Re[3]: C++/CLI
□投稿者/ WebSurfer (1271回)-(2017/07/24(Mon) 15:43:38)
No84633 (アルマジロ さん) に返信

Double::Parse メソッドを使うのではないすか?

Double::Parse メソッド (String^)
https://msdn.microsoft.com/ja-jp/library/fd84bdyt(v=vs.110).aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-3



#WinForms アプリを作っているように見えますが、そうだとすると C# を使わないのは何故でしょう? 
Microsoft は "C++/CLI を使った Windows フォーム アプリケーションの作成は推奨しません" というこ
とだそうですが。

Visual C++ での互換性に影響する変更点
https://msdn.microsoft.com/ja-jp/library/bb531344(v=vs.110).aspx
引用返信 編集キー/
■84710 / inTopicNo.5)  Re[4]: C++/CLI
□投稿者/ アルマジロ (3回)-(2017/07/28(Fri) 18:28:11)
No84638 (WebSurfer さん) に返信
> ■No84633 (アルマジロ さん) に返信
>
> Double::Parse メソッドを使うのではないすか?
>
> Double::Parse メソッド (String^)
> https://msdn.microsoft.com/ja-jp/library/fd84bdyt(v=vs.110).aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-3
>
>
>
> #WinForms アプリを作っているように見えますが、そうだとすると C# を使わないのは何故でしょう? 
> Microsoft は "C++/CLI を使った Windows フォーム アプリケーションの作成は推奨しません" というこ
> とだそうですが。
>
> Visual C++ での互換性に影響する変更点
> https://msdn.microsoft.com/ja-jp/library/bb531344(v=vs.110).aspx

度々の返信有難う御座います。
おっしゃる通り、今回はC++/CLIを使う理由はないので、C#で書き直してみました。

引き続きの質問になるのですが、読み込みたいファイルが数値と文字の混合したcsvファイルとなっています。

数値はそのままfloat.Parseを使って数値配列データに書き込むのですが、

たまに文字列が混在しているとParse出来ずにエラーになってしまいます。

文字列の場合は、文字列と識別して 0 の数値を強制的に入力したいのですが、

どのようにしたらよいでしょうか?

public partial class Form1 : Form
{
public int height = 0;
public int width = 0;

public float[,] ReadToData;

public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
label1.Text = openFileDialog1.FileName;

StreamReader sr = new StreamReader(openFileDialog1.FileName, Encoding.GetEncoding("Shift_JIS"));
string strStream = sr.ReadToEnd();
System.StringSplitOptions option = StringSplitOptions.RemoveEmptyEntries;

string[] lines = strStream.Split(new char[] { '\r', '\n' }, option);
char[] spliter = new char[1] { ',' };

int heightLength = lines.Length;
int widthLength = lines[0].Split(spliter, option).Length;

ReadToData = new float[heightLength, widthLength];

for(int i=0; i<heightLength; i++)
{
for(int j=0; j<widthLength; j++)
{
string[] readStrData = lines[i].Split(spliter, option);
ReadToData[i, j] = float.Parse(readStrData[j]);
}
}
this.height = heightLength;
this.width = widthLength;
}
}
}
引用返信 編集キー/
■84711 / inTopicNo.6)  Re[5]: C++/CLI
□投稿者/ WebSurfer (1272回)-(2017/07/28(Fri) 19:23:10)
No84710 (アルマジロ さん) に返信

> 文字列の場合は、文字列と識別して 0 の数値を強制的に入力したいのですが、

コードはインデントされてなくて読みにくいので読んでません。(図表モードにしてください)

その上での上記の質問に対する回答ですが、TryParse メソッドを使って false が返ってきた
ら「文字列と識別して 0 の数値を強制的に入力」してはいかがですか?

引用返信 編集キー/
■84712 / inTopicNo.7)  Re[6]: C++/CLI
□投稿者/ アルマジロ (4回)-(2017/07/28(Fri) 20:04:10)
図表モードにしてませんでした、申し訳ないです。

こんな感じですかね?

                        if(float.TryParse(readStrData[j], out ReadToData[i,j]))
                        {

                        }
                        else{
                            ReadToData[i, j] = 0;
                        }

引用返信 編集キー/
■84714 / inTopicNo.8)  Re[7]: C++/CLI
□投稿者/ Azulean (843回)-(2017/07/28(Fri) 22:51:31)
No84712 (アルマジロ さん) に返信
if ブロックの中に何も書かないぐらいなら、論理を反転しましょうよ。

if(!float.TryParse(readStrData[j], out ReadToData[i,j]))
{
  ReadToData[i, j] = 0;
}

引用返信 編集キー/
■84716 / inTopicNo.9)  Re[7]: C++/CLI
□投稿者/ WebSurfer (1273回)-(2017/07/28(Fri) 23:22:51)
No84712 (アルマジロ さん) に返信

> こんな感じですかね?

やってみたんじゃないですか? それで OK なら聞く必要はないと思うのですが、ダメだったのですか?


#なんで Double でなくて float を使っているのでしょう? 昔(かなり昔)の連続したメモリ空間が
 64 kB しか取れなかった頃の話ならともかく・・・
引用返信 編集キー/
■84719 / inTopicNo.10)  Re[8]: C++/CLI
□投稿者/ Jitta (307回)-(2017/07/29(Sat) 16:32:06)

No84712 (アルマジロ さん) に返信
>
> #なんで Double でなくて float を使っているのでしょう? 昔(かなり昔)の連続したメモリ空間が
>  64 kB しか取れなかった頃の話ならともかく・・・
補足
http://www.pro.or.jp/~fuji/mybooks/cdiag/cdiag.4.4.html
引用返信 編集キー/
■84766 / inTopicNo.11)  Re[9]: C++/CLI
□投稿者/ アルマジロ (5回)-(2017/08/01(Tue) 19:01:05)
No84719 (Jitta さん) に返信
> 
> ■No84712 (アルマジロ さん) に返信
>>
>>#なんで Double でなくて float を使っているのでしょう? 昔(かなり昔)の連続したメモリ空間が
>> 64 kB しか取れなかった頃の話ならともかく・・・
> 補足
> http://www.pro.or.jp/~fuji/mybooks/cdiag/cdiag.4.4.html

各位、ご指摘有難う御座います。 勉強になります。

続けての質問になってしまい、誠に申し訳ありませんが、

ボタン1を押して、ReadToData1[i,j]に数値データを読み込んでグラフ化、

ボタン2を押して、ReadToData2[i,j]に数値データを読み込んでグラフ化、

というところまで無事できました。

その後、ReadToData1[i,j]の数値データから、ReadToData2[i,j]の数値データを引いて

ReadToData3[i,j]という新たな数値情報を演算処理させたいと思っています。

ところが下記のような内容でReadToData3[i,j]のデータをグラフ化させようとするとエラーが起きます。

ボタン1、もしくはボタン2を押してデータを読み込んだ時点で、

オブジェクトがNullで良いかどうか確認してください、というエラーが出ます。

おそらく、ReadToData1[i,j]を読み込んだ時点で、ReadToData2[i,j]の情報がないので

エラーが起きているのだと思っていますが、ReadToData2[i,j]にまだ情報が格納されていない場合は

計算させない、といった構文をつくらないといけないのでしょうか?

ReadToData1[i,j] と ReadToData2[i,j] の配列長は同一です。


初歩的質問ばかりで誠に申し訳ありません。




       private void Form1_Paint(object sender, PaintEventArgs e)
        {

            for (int i = 0; i < height1; i++)
            {
                gra.DrawEllipse(pen1, i, ((ReadToData1[i, 0] * (100/-Graph)) - OFFSET1 + 150), 1, 1);
            }

            for (int i = 0; i < height2; i++)
            {
                gra.DrawEllipse(pen1, i, ReadToData2[i, 0], 1, 1);
            }

            for (int i = 0; i < height2; i++)
            {
                gra.DrawEllipse(pen2, i, (ReadToData2[i, 0]-ReadToData1[i,0]), 1, 1);
            }

引用返信 編集キー/
■84785 / inTopicNo.12)  Re[10]: C++/CLI
□投稿者/ WebSurfer (1277回)-(2017/08/02(Wed) 14:08:27)
No84766 (アルマジロ さん) に返信

一つの疑問が解決すると、それが次の疑問を生んで、次から次へと質問を繰り返すのは
ここのような(多分 know-how の蓄積も目的としている)サイトでは好ましくないと思
います。

何故なら、何かをキーワードにしてググってここにたどり着いた人が見ると何が何だか
分からないという内容になってしまうので。

最初の質問:

> TableData[i]の文字配列を冒頭で宣言した DATA[i] に数値配列として格納する方法を
> 教えて頂けませんでしょうか?

は、パースできない文字列の場合の対応も含めて解決したと理解していますが、そうで
あればここはクローズして、No84766 の質問は新たに別のスレッドを立てて質問してい
ただければと思います。

なお、その際には、質問の内容を表す表題を付けていただくようお願いします。(ここの
ような C++/CLI は NG)
引用返信 編集キー/

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


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

このトピックに書きこむ