現在PICマイコンでPCからGPSの座標データを取得し,そのデータ列から必要な部分だけ抜き出す処理をくんでいるんですがうまくいきません。
pcとマイコンの接続はrs23-2c
コンパイラはccsc
pic:16f877
GPSデータ↓
@051125012151N3529558E13638533G009+00021E0000N0000D0003
このデータのN以降の「3529558」とE以降の「13638533」の文字列を数値にしたい。
delay_ms(300);
output_b(0b00000001);//デバック用LED点灯
delay_ms(300);
gets(mes); //ここでGPSデータをmesに代入する
output_b(0b00000011);
len_N=0;
for(i=0;i<58;i++){
if(mes[i]=='N'){
len_N=i;
break;
}
}
printf("\r\n");
n=atoi(mes[len_N+1]); //ここで試しに一文字分だけ数値にする処理を行ったが処理が停止する。
printf("n:%ld",n);
アドバイスお願いします
No.4ベストアンサー
- 回答日時:
以下のようにすると切り出しぐらいはできるようです。
ただ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");
}
}
No.6
- 回答日時:
>ポインタ操作ができないようです
ということであれば、
文字列の処理をどうするのか補足してください。
文字列を数字にするのは変数演算でできると思うのですが、できませんか?
この回答への補足
回答者の方々のおっしゃるとおり、
longでもビット数が足りないことが分かりました。
いままで授業ではPC上のソフトしか組んだことがないので
まったくの無知でした。
どっちみち、うまく取り出したとしても変数に
格納できないし、unsignedではなんか反則技みたいで
最終的には
dig(int) min(int) sec(float) と三つに分けるつもりなので
ばらばらで処理していきたいと思います
ちなみに
16F877に書き込んだところ
すでにRAMがいっぱいです。
cssのマニュアルには
なるべくローカル変数をへらせ
としかかいてありません
数回しか行かない関数はメイン文に入れろ
と先生はいうので
そのとおりにしてもぜんぜん足らないので
PICを変えるべきなのか迷っています。
No.5
- 回答日時:
そういえばこれ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;
}
ということではないかと思います。
No.3
- 回答日時:
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'を検出する処理は問題ないと思います。
No.2
- 回答日時:
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;
}
この回答への補足
一部参考にしてみましたがやはりポインタ操作とのころで
処理が停止しています。
その問題を回避しつつ、数字の文字列をだすには
どうしたらいいでしょうか?
No.1
- 回答日時:
atoi関数の考え方がまずいですよね。
atoiに与える引数はキャラクタ型ポインタですからnullポインタが出てくるところまで動作してしまうんではないでしょうか。
char buf[2] = {0,0};
とでもしておいて、
buf[0] = mes[len_N+1];
n=atoi(buf);
printf("n:%d",n);
とでもすればうまくいきそうにみえますね。
この回答への補足
知人いわく
このコンパイラはポインタ操作ができないらしいのです
どうしたらいいでしょうか?
また文字列を取り出す時にはどうしたらいいでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- Visual Basic(VBA) vba 等間隔の列に対しての計算 6 2022/05/17 20:15
- C言語・C++・C# [C言語] コメント文字列を無視して、数値データを読み込むプログラム部分について 5 2022/10/05 11:03
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- PHP 文字列を段落で分ける方法を教えて下さい。 2 2023/03/09 10:03
- その他(プログラミング・Web制作) COBOL数値転記をCOPY句内での仕様 6 2022/06/15 18:48
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- Visual Basic(VBA) VBAで大量データの処理 3 2022/11/15 21:53
- その他(プログラミング・Web制作) pythonでクラスで複数のメソッドを利用する方法 2 2022/04/15 04:17
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・「みんな教えて! 選手権!!」開催のお知らせ
- ・漫画をレンタルでお得に読める!
- ・「黒歴史」教えて下さい
- ・2024年においていきたいもの
- ・我が家のお雑煮スタイル、教えて下さい
- ・店員も客も斜め上を行くデパートの福袋
- ・食べられるかと思ったけど…ダメでした
- ・【大喜利】【投稿~12/28】こんなおせち料理は嫌だ
- ・前回の年越しの瞬間、何してた?
- ・【お題】マッチョ習字
- ・モテ期を経験した方いらっしゃいますか?
- ・一番最初にネットにつないだのはいつ?
- ・好きな人を振り向かせるためにしたこと
- ・【選手権お題その2】この漫画の2コマ目を考えてください
- ・2024年に成し遂げたこと
- ・3分あったら何をしますか?
- ・何歳が一番楽しかった?
- ・治せない「クセ」を教えてください
- ・【大喜利】【投稿~12/17】 ありそうだけど絶対に無いことわざ
- ・【選手権お題その1】これってもしかして自分だけかもしれないな…と思うあるあるを教えてください
- ・集合写真、どこに映る?
- ・自分の通っていた小学校のあるある
- ・フォントについて教えてください!
- ・これが怖いの自分だけ?というものありますか?
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・10代と話して驚いたこと
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
double型の値をchar配列に変換...
-
絶対パスからのファイル名の切...
-
文字列から空白を取り除きたい...
-
System32のパス取得方法
-
c言語でユーザ関数を利用して入...
-
ネットワークにつながっている...
-
C言語のファイル出力について
-
C言語 初心者です。
-
c++ 文字列を入力して、一文字...
-
TCHAR文字列?の特定部分の数字...
-
RGBをCMYKに変換するプログラム
-
C言語の入力した文字を反転させ...
-
'const char *' 型は 'char *' ...
-
Win32APIでのエディットボック...
-
単語を読み取る(c言語)
-
ftoa の作り方
-
Linuxでフォルダ内全ファイル名...
-
文字列の中のカンマを消したい
-
複数桁10進数の*桁目だけを抽出...
-
「Aに対するBの割合」と「Aに対...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
文字列から空白を取り除きたい...
-
CStringをwchar_tに変換したい
-
C言語のfor文です。 繰り返しの...
-
charでの計算?
-
テキストデータをそのままバイ...
-
fgetsなどのときのstdinのバッ...
-
charからLPTSTRへの変換方法
-
double型の値をchar配列に変換...
-
C言語プログラミングについて(...
-
str系関数を使わずに二つの文字...
-
ネットワークにつながっている...
-
'const char *' 型は 'char *' ...
-
干支のプログラム
-
配列をnビットシフトする
-
間接操作のレベルとは
-
c言語配列の結合についてです。...
-
間接参照のレベルが異なっています
-
c++ 文字列を入力して、一文字...
-
C言語 ミリ秒を日付に変換には
-
switch文で文字を比較すること...
おすすめ情報