アプリ版:「スタンプのみでお礼する」機能のリリースについて

入力された文字列を判断して、それぞれの対応をさせるものを作りたいのですが、
下記のようにしたとき、どうしてもうまくいかないところがあります。
1)例えば、[W,B,C,1,2,3]と連続して入力したら、ID2で[123]と10進数に変換したいのに、
[3,0,0]以降になると、16進数で表した時は(300=12C)になるはずなのに(300=2C)で変換されてしまう。0~299までは正常に変換される。
2)下記「←」の部分で、ID[0~2]の中身がすべて数字であるときにatoiを実行したいけど、
isalphaでは一文字しか判定されないので、他に方法はあるのかどうか…配列全部を判定あできるやり方はあるのでしょうか?

どなたかわかる方がいらっしゃいましたら、ヒントなり頂けないでしょうか?お願いします。

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_RW[0]=='R'){
printf("RR");
}else if(COM_RW[0]=='W'){
if(isdigit(COM[3])){
for(i=0,j=3;j<6;j++,i++)
ID[i]=COM_RW[j];
if(isdigit(ID[2]))  <----
ID2=atoi(ID);
}
}else if(COM_RW[0]!='\r'){
printf("ERROR.2:once more input.");
}
printf("%lu",ID2);
ID2=0;
printf("\r\n");
}

A 回答 (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]にゴミが入っている可能性があるので、その対策も必要です。

この回答への補足

>・main()の型が正しくない
それでしたら、似たようなものを以前に読んだことがあります。
しかし、サンプルソースや上司の書いたコードにもvoidが使われていたので、いいものなのかと思っておりました。以後は使わないようにします。

>getc()にはFILE*型の引数が必要
仕様書を見たところ、getc()とgetchar()は両方ともgetch()として定義されているようでした。

>16進数への変換に関係したコードが無い
デバッグ画面では、数値が10進数ではなく16進数で表示されていたため、このように書きました。実際に表示されるのは、
入力→300(12C) なら 出力→44(2C) ということでした。

補足日時:2009/05/26 18:37
    • good
    • 0
この回答へのお礼

残りですが、2)は提示して頂いたif文に若干付け加えをして、問題なくいけました。
atoi()ですが、使うのをやめてstrtol()という関数を使って動作させることにしました。こちらの方がしっくりくるようです。

結局は質問で提示したコードとは大幅に違うものが出来ました(まだ途中です)が、回答者さま達の忠告(アドバイス)を読んで、見直すところが多々ありました。
色々に答えてくださりありがとうございました。

お礼日時:2009/05/26 18:43

#1で色々言われてますがもう一点。



・文字列(char配列)を扱う時には終端文字分まで確保しなければならず、また終端設定は基本的に自力で行わなければならないが、その辺りがすっぽり抜けている
これでatoi(ID)が期待通りに動いているのは奇跡というかただのマグレです。

なお2についてはsscanf()を使えば比較的楽に出来るでしょう。

この回答への補足

終端設定と言うと…'\0'のことでしょうか?
最後にいれなければと思っているのですが、そこまで考えていられなくて…

>なお2についてはsscanf()を使えば比較的楽に出来るでしょう。
それは思ったのですが、どうやらscanf()系が使えないコンパイラみたいなので、別の方法を探しています。
ちなみに、ccscのpiccコンパイラです。

補足日時:2009/05/25 22:53
    • good
    • 0

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");
}

補足日時:2009/05/25 22:50
    • good
    • 0

> 入力された文字列を判断して、それぞれの対応をさせるものを作りたい



どんな入力に対してどんな結果を得たいのかが質問文からは分かりません。補足をお願いします。

> (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]がそれにあたります。書き間違いでした。

補足日時:2009/05/25 22:39
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!