- ベストアンサー
数字変換の問題についての質問
- 入力された文字列を判断して、それぞれの対応をさせるものを作りたい。しかし、うまくいかない部分がある。
- 16進数で表される300が2Cに変換されてしまう問題が発生している。
- 配列の要素がすべて数字であるかどうかを判定する方法がわからない。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
No.1です。 >>・main()の型が正しくない >どう正しくないのでしょうか? 標準的なC言語では、main()の返り値型はvoidではなくてintと決まっています。http://www.kouno.jp/home/c_faq/c11.html の 11.12 とか 11.15 を見てください。 >>・getc()に引数がない >getc()に使う引数とはなんでしょうか?前もこのままで使っていました。とくに問題はなかったです。 標準的なC言語では、getc()にはFILE*型の引数が必要です。getchar()ならば引数は不要です。 もっとも、「scanf()系が使えない」ということなので標準的なC言語ではないようですね。とするとprintf()やatoi()もどんな仕様になっているか分かったものではありませんが。 >10進で300は16進にすると12cになるはずなのに、なぜか2cに変換されてしまいます。 提示されているプログラムには、どこにも16進数への変換に関係したコードが無いように見えます。 atoi()が動いているように見えるのはNo.3さんの書いているとおり偶然です。C言語の文字列の最後には '\0' が必要です。ID[0]~ID[2]に必ず文字が入るのであれば、uchar ID[4];と宣言して、ID[3]='\0';としてください。 > 2)下記「←」の部分で、ID[0~2]の中身がすべて数字であるときにatoiを実行したいけど、 その3文字だけならば if (isdigit(ID[0]) && isdigit(ID[1]) && isdigit(ID[2])) とでもすればいいでしょう。 文字数が3文字と決まっていない場合はループで判定することになります。 最初のfor(a=0;a<7;a++)のループを途中でbreakで抜けた場合には、COM[4]とかID[2]にゴミが入っている可能性があるので、その対策も必要です。
その他の回答 (3)
- D-Matsu
- ベストアンサー率45% (1080/2394)
#1で色々言われてますがもう一点。 ・文字列(char配列)を扱う時には終端文字分まで確保しなければならず、また終端設定は基本的に自力で行わなければならないが、その辺りがすっぽり抜けている これでatoi(ID)が期待通りに動いているのは奇跡というかただのマグレです。 なお2についてはsscanf()を使えば比較的楽に出来るでしょう。
補足
終端設定と言うと…'\0'のことでしょうか? 最後にいれなければと思っているのですが、そこまで考えていられなくて… >なお2についてはsscanf()を使えば比較的楽に出来るでしょう。 それは思ったのですが、どうやらscanf()系が使えないコンパイラみたいなので、別の方法を探しています。 ちなみに、ccscのpiccコンパイラです。
COM_RWの初期化部分はどうなっているのでしょうか。
補足
こちらにすみません、若干訂正しました。 COM_RW=COMでした。COMで統一させておきました。 void main(){ uchar a,c,i,j,COM[7],ID[3]; ulong ID2=0; for(a=0;a<7;a++){ c=getc(); COM[a]=c; if(c=='\r') break; printf("%c",c); }printf("\r\n"); if(COM[0]=='R'){ printf("RR"); }else if(COM[0]=='W'){ if(isdigit(COM[3])){ for(i=0,j=3;j<6;j++,i++) ID[i]=COM[j]; if(isdigit(ID[2])) ID2=atoi(ID); } }else if(COM[0]!='\r'){ printf("ERROR.2:once more input."); } printf("%lu",ID2); ID2=0; printf("\r\n"); }
- salsberry
- ベストアンサー率69% (495/711)
> 入力された文字列を判断して、それぞれの対応をさせるものを作りたい どんな入力に対してどんな結果を得たいのかが質問文からは分かりません。補足をお願いします。 > (300=2C)で変換されてしまう。 この部分も意味が取れませんでした。 また、上記のコードは標準的なCコンパイラではコンパイルできません。ちゃんとコンパイルできるものを貼付けてください。 ・main()の型が正しくない ・uchar, ulongなど非標準的な型を使っている ・getc()に引数がない ・getc()やprintf()を使うのにstdio.hをインクルードしていない ・同様に、isdigit()を使うのにctype.hを~ ・同様に、atoi()を使うのにstdlib.hを~ ・COM_RW[]という変数は定義されていない
補足
例にあるように、[W,B,C,1,2,3]と入力したら文字・[WBC]と数字[123]と判断して、[1,2,3]の部分を[123]と数値にしたいのです。 > (300=2C)で変換~ は、10進で300は16進にすると12cになるはずなのに、なぜか2cに変換されてしまいます。atoiでなく、手動でやった時もそう変換されました。 >・main()の型が正しくない どう正しくないのでしょうか? >・uchar, ulongなど非標準的な型を使っている 書いてないですが、最初に#defineで定義しています。 >・getc()に引数がない getc()に使う引数とはなんでしょうか?前もこのままで使っていました。とくに問題はなかったです。 >・getc()やprintf()を使うのにstdio.hをインクルードしていない >・同様に、isdigit()を使うのにctype.hを~ >・同様に、atoi()を使うのにstdlib.hを~ すべて一番最初に定義しています。書くと入らないかと思ったので、省略していました。 >・COM_RW[]という変数は定義されていない すみません、最初のCOM[7]がそれにあたります。書き間違いでした。
お礼
残りですが、2)は提示して頂いたif文に若干付け加えをして、問題なくいけました。 atoi()ですが、使うのをやめてstrtol()という関数を使って動作させることにしました。こちらの方がしっくりくるようです。 結局は質問で提示したコードとは大幅に違うものが出来ました(まだ途中です)が、回答者さま達の忠告(アドバイス)を読んで、見直すところが多々ありました。 色々に答えてくださりありがとうございました。
補足
>・main()の型が正しくない それでしたら、似たようなものを以前に読んだことがあります。 しかし、サンプルソースや上司の書いたコードにもvoidが使われていたので、いいものなのかと思っておりました。以後は使わないようにします。 >getc()にはFILE*型の引数が必要 仕様書を見たところ、getc()とgetchar()は両方ともgetch()として定義されているようでした。 >16進数への変換に関係したコードが無い デバッグ画面では、数値が10進数ではなく16進数で表示されていたため、このように書きました。実際に表示されるのは、 入力→300(12C) なら 出力→44(2C) ということでした。