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

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

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

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

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Visual Studio

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

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

Q&A

解決済

1回答

20801閲覧

c#でハンドルされていない例外が発生します

dcb1221

総合スコア7

C#

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

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Visual Studio

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

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

0グッド

0クリップ

投稿2016/10/29 14:03

###前提・実現したいこと
現在c#を学習している初心者です。
今回作成しているプログラムは、zaifというbitcoinの取引所のapi(https://corp.zaif.jp/api-docs/)を使用して、bitcoinの終値を定期的に更新し、表示をするアプリケーションです。今回は、プログラムの勉強と、jsonというフォーマットの勉強もかねて、外部のライブラリ(json.netとかDynamic json)などは使わず、自分でjsonをシリアライズすることにしました。

###発生している問題・エラーメッセージ
テストすると、ビルドはできるのですが、ハンドルされていない例外が発生します。
表示されるポップアップ

###該当のソースコード
※コメントは自分が分かる程度にしか書いていません。
もっと無駄のないソースコードの書き方などありましたらアドバイスいただけると幸いです。

C#

1using System; 2using System.Collections.Generic; 3using System.ComponentModel; 4using System.Data; 5using System.Drawing; 6using System.Linq; 7using System.Text; 8using System.Windows.Forms; 9using System.Net; 10 11 12 13 14 15namespace WindowsFormsApplication14 16{ 17 18 public partial class Form1 : Form 19 { 20 21 public Form1() 22 { 23 InitializeComponent(); 24 } 25 public static int CountChar(string s, char c) 26 { 27 return s.Length - s.Replace(c.ToString(), "").Length; 28 } 29 public void jsondecode(string input) 30 31 { 32 33 34 } 35 36 private void Form1_Load(object sender, EventArgs e) 37 { 38 timer1.Start(); 39 } 40 41 private void timer1_Tick(object sender, EventArgs e) 42 { 43 44 using (WebClient webClient = new WebClient()) 45 { 46 47 string str = webClient.DownloadString("https://api.zaif.jp/api/1/last_price/btc_jpy"); 48 Boolean y = false;//キーかどうか 49 Boolean y2 = false;//値かどうか 50 int len = str.Length;//取得した文字数取得 51 int cc = CountChar(str,',');//,の数をカウント 52 string[,] str2 = new string[cc,2]; 53 string[] stra = new string[len];//文字列を分割して入れるための配列宣言 54 int y3 = 0;//何個目のオブジェクトか記録用 55 for (int i = 0; i < len; i++ ) {//文字数回繰り返すfor 56 stra[i] = str.Substring(i,1);//i文字目の文字をstra[i]に代入 57 } 58 for (int i = 0; i < len; i++) 59 { 60 61 switch ( stra[i] ) 62 { 63 case "\"": 64 if(y == false) 65 { 66 y = true; 67 68 } 69 else 70 { 71 y = false; 72 73 } 74 break; 75 case ":": 76 y2 = true; 77 break; 78 case "{":break; 79 case "}":break; 80 case "^":break; 81 case ",": 82 if (y2 == true) 83 { 84 y2 = false; 85 } 86 y3++; 87 break; 88 case "[":break; 89 case "]":break; 90 default: 91 if (y == true || y2 == true) 92 { 93 if (y == true) { 94 str2[y3 - 1, 0] = str2[y3 - 1, 0] + stra[i]; 95 } 96 if (y2 == true) 97 { 98 str2[y3 - 1, 1] = str2[y3 - 1, 1] + stra[i]; 99 100 } 101 } 102 break; 103 104 105 106 } 107 108 109 } 110 111 112 113 label1.Text = str2[0, 0] + str2[0, 1] + "円"; 114 115 } 116 } 117 118 private void button1_Click(object sender, EventArgs e) 119 { 120 121 122 } 123 124 } 125 126 }

###試したこと
googleで検索し、ほかの方の事例を見ましたが、当方の検索能力の低さと、知識不足が故に原因特定には至りませんでした。

###補足情報
visual studio 2015 communityを使用しています。

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

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

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

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

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

guest

回答1

0

ベストアンサー

こんにちは。

"https://api.zaif.jp/api/1/last_price/btc_jpy"

の内容は{"last_price": 75470.0}でした。,が入っていないので、ccの値は0になります。
すると、str2はstring[0, 2]なのでこの時点で何かよろしくないことがおきている感じがします。
ただし、例外メッセージからここでは例外になっていないと思います。

そのまま処理が継続され、:y2=true;となり、次のブランクdefault:へ入り、str2[y3 - 1, 1]をアクセスしようとしてy3が0なので、str[-1, 1]をアクセスし表示されている例外に至っていると思います。

もっと無駄のないソースコードの書き方などありましたらアドバイスいただけると幸いです。

根本的な問題がありそうです。
この手のデシリアライズを行う場合、再帰定義かスタックを使うのが一般的な方法ですが使っていませんし、それに変わる構造もないようです。
ですので{"asks":[[30000.0, 0.1],[30010.0, 0.2],...], ...}のようなJsonデータを読めないことが予想できます。

JSON の紹介にJson書式の定義が分かりやすく書いてあります。
これを見れば分かるようにvalueの中にobjectが含まれています。
つまり、最上位のobjectを解析するプログラムを作り、それがvalue処理まで進んで再度objectが出てきたら、objectを解析する大本のプログラムを再帰的に呼び出すと多くのコードを書かなくて済みます。
再帰定義を使わない場合は、{[でスタックへプッシュ、}]でスタックからポップする処理が必要になります。
シリアライザはコード量は少ないのですが、意外に難易度が高いのです。

解析するJsonデータ構造は既知ですから、C#が標準で持っているJsonシリアライザを使える筈です。まずはそれを使いこなすことも視野に入れると楽しくプログラミングできるような気がします。

投稿2016/10/29 14:47

編集2016/10/29 16:01
Chironian

総合スコア23272

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

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

dcb1221

2016/10/29 14:53

ご丁寧に回答ありがとうございます。’C#が標準で持っているJsonシリアライザ’があることを知りませんでした。教えていただきました情報をもとにJsonについて勉強したいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問