teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

質問の情報追加を受けて追記

2019/08/17 00:30

投稿

thkana
thkana

スコア7735

answer CHANGED
@@ -25,11 +25,23 @@
25
25
 
26
26
  len = (unsigned char*)txData(i2-1);
27
27
  ```
28
- なにをやりたいのか私には全くわかりません。文字列型の変数にカッコをつけるという謎。そしてそのなにかをunsigned char*にキャストしてunsigned char型の変数に代入しようという謎。
28
+ ~~なにをやりたいのか私には全くわかりません。文字列型の変数にカッコをつけるという謎。そしてそのなにかをunsigned char*にキャストしてunsigned char型の変数に代入しようという謎。~~
29
+ 2個めのカンマの前一文字がデータ長を表しているということなら、統一的にstrtol()/strtoul()で処理してもいいですけれど、一文字取り出したのを文字列に再構成とかちょっと面倒です。
30
+ かならず一桁の値だということが確かなら
31
+ ` len = txData[i2-1]-'0';`
32
+ でも十分、とも言えます。
33
+ (「数字」と「数値」の関係は把握していますか?)
29
34
 
30
35
  ```
31
36
  CAN_Box3:53:22: error: invalid cast from type 'String' to type 'byte {aka unsigned char}'
32
37
 
33
38
  txBuf[i] = (byte)charData;
34
39
  ```
35
- これも先程と同様。(byte)をつけても文字列の内容を解釈してくれるわけではありません。先程と同様にstrtoulあたりで「変換」した後、charにキャストするのが適切かと思います。
40
+ これも先程と同様。(byte)をつけても文字列の内容を解釈してくれるわけではありません。先程と同様にstrtoulあたりで「変換」した後、charにキャストするのが適切かと思います。
41
+
42
+ ### 追記
43
+ 通信を行う際には、原則として「エラー」の発生を無視してはいけません。ノイズであったり接続断であったり、いろいろな状況が考えられるのであらゆる場合に完全に対応というのは難しいですが、それでも容易に考えられる破滅的な状況は考慮すべきです。
44
+
45
+ 今回、データ本体(データ長のあとの部分)をwhileループで取得しようとしています。ノイズか何かで改行コードを拾いそこなったらどうなりますか。次の行とデータが繋がって','が多いデータ列となり、容易にデータ数が8を超えてtxBuf[8]に対してバッファオーバーフローを起こし、プログラムの異常動作を引き起こしかねません。ここは、先に取得してあるlenを最大値としてループを回すべきでしょう。
46
+ 一方、','をロストした場合にはデータ数が足りなくなります。多いにしろ少ないにしろ、取得したデータ数とlenの値を比較すればエラーの検出は出来ますが、エラーが検出された場合そのパケットをどうするか(単に無視する/捨てるか、再送リクエストの仕組みを作るか等)はシステム全体の動作に鑑みてあなたが決めて下さい。
47
+ それに関連して、lenは1~8という範囲が仕様に示されているのなら、その範囲にあることをチェックすべきです。