- ベストアンサー
文字列配列のほしい部分だけを抜き出して数値にする方法(PIC)
- 現在PICマイコンでPCからGPSの座標データを取得し、そのデータ列から必要な部分だけ抜き出す処理を行う方法について説明します。
- GPSデータのN以降の数値とE以降の数値を文字列から数値に変換する方法について説明します。
- アドバイスとして、正しい数値への変換が行われない可能性があるため、データの取得と変換処理の順序や条件文の確認をおすすめします。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
以下のようにすると切り出しぐらいはできるようです。 ただRAM384バイトしかないので変数領域に気をつけてください。 一応コンパイルは通るようです。実際の挙動がそのようになるかは確認していません。 また、よく考えるとatoi()ではだめですよね。 CCS-Cのlong型は16ビットですからunsigned指定をしても65535までしかカウントできません。 サンプルにある13638533なんて演算できませんもんね。 ここを数値化する方法は別に考えないといけませんね。 #include <TEST.H> char mes[60] = "@051125012151N3529558E13638533G009+00021E0000N0000D0003"; void main() { int numN=0 ; int Nflag=0; int numE=0; int Eflag = 0; int i; char mesN[10] = {0,0,0,0,0,0,0,0,0,0}; char mesE[10] = {0,0,0,0,0,0,0,0,0,0}; setup_counters(RTCC_INTERNAL,RTCC_DIV_2); setup_port_a(NO_ANALOGS); setup_adc(ADC_CLOCK_INTERNAL); while(1){ printf("Input> ");printf(mes); printf("\r\n"); for(i=0;i<58;i++){ if ( mes[i]=='N' ){ Nflag = 1; Eflag = 0; } if ( mes[i]=='E' ){ Nflag = 0; Eflag = 1; } if ( mes[i]=='G' ){ Nflag = 0; Eflag = 0; } if ( Nflag ) { mesN[numN] = mes[i]; numN++; } if ( Eflag ) { mesE[numE] = mes[i]; numE++; } } printf( mesN ); printf("\r\n"); printf( mesE ); printf("\r\n"); } }
その他の回答 (5)
- rentahero
- ベストアンサー率53% (182/342)
>ポインタ操作ができないようです ということであれば、 文字列の処理をどうするのか補足してください。 文字列を数字にするのは変数演算でできると思うのですが、できませんか?
補足
回答者の方々のおっしゃるとおり、 longでもビット数が足りないことが分かりました。 いままで授業ではPC上のソフトしか組んだことがないので まったくの無知でした。 どっちみち、うまく取り出したとしても変数に 格納できないし、unsignedではなんか反則技みたいで 最終的には dig(int) min(int) sec(float) と三つに分けるつもりなので ばらばらで処理していきたいと思います ちなみに 16F877に書き込んだところ すでにRAMがいっぱいです。 cssのマニュアルには なるべくローカル変数をへらせ としかかいてありません 数回しか行かない関数はメイン文に入れろ と先生はいうので そのとおりにしてもぜんぜん足らないので PICを変えるべきなのか迷っています。
- rentahero
- ベストアンサー率53% (182/342)
そういえばこれGPSですよね。ということはわたってくる数値は固定小数点だったはず。 であれば、 float n, e, pow; n = 0; pow = 10; for(i = 1; mes[len_N + i] >= '0' && mes[len_N + i] <= '9'; i++) { n += (mes[len_N + i] - '0') * pow; pow /= 10; } e = 0; pow=100; for(i = 1; mes[len_E + i] >= '0' && mes[len_E + i] <= '9'; i++) { e += (mes[len_E + i] - '0') * pow; pow /= 10; } ということではないかと思います。
お礼
参考にさせていただきます。
- rentahero
- ベストアンサー率53% (182/342)
rentaheroです。 PICは触ってないので、一般人で。 そもそもatoi(3)に対する引数の型が間違ってます。 atoiは文字列へのポインタを渡さなければなりません。 mesはchar のポインタか配列のようですから、 mes[len_N+1]はcharそのものです。 1文字だけ数値にしたい場合は、 n = mes[len_N+1]-'0'; とするべきだし、 同じ位置からintとして数値を取り出したい場合は、 n = atoi(&mes[len_N + 1]); または n = atoi(mes + len_N + 1); となります。 'N'を検出する処理は問題ないと思います。
補足
ポインタ操作ができないようです
- mac_res
- ベストアンサー率36% (568/1571)
PCでやってもatoi(3)はエラーになりますね。 #include <stdio.h> #include <stdlib.h> #define NGPSBUFF 58 int main(void) { char mes[NGPSBUFF]; int i; long N, E; char *n, *e; gets(mes); //ここでGPSデータをmesに代入する for (i = 0; i < NGPSBUFF; i++) { if (mes[i] == 'N') break; } ++i; n = &mes[i]; for (; i < NGPSBUFF; i++) { if (mes[i] == 'E') break; } mes[i] = '\0'; ++i; e = &mes[i]; for (; i < NGPSBUFF; i++) { if (mes[i] == 'G') break; } mes[i] = '\0'; N = atoi(n); printf("n:%ld\n", N); E = atoi(e); printf("e:%ld\n", E); return 0; }
補足
一部参考にしてみましたがやはりポインタ操作とのころで 処理が停止しています。 その問題を回避しつつ、数字の文字列をだすには どうしたらいいでしょうか?
- techa
- ベストアンサー率60% (41/68)
atoi関数の考え方がまずいですよね。 atoiに与える引数はキャラクタ型ポインタですからnullポインタが出てくるところまで動作してしまうんではないでしょうか。 char buf[2] = {0,0}; とでもしておいて、 buf[0] = mes[len_N+1]; n=atoi(buf); printf("n:%d",n); とでもすればうまくいきそうにみえますね。
補足
知人いわく このコンパイラはポインタ操作ができないらしいのです どうしたらいいでしょうか? また文字列を取り出す時にはどうしたらいいでしょうか?
お礼
ありがとうございます、参考にします