入力された文字列を判断して、それぞれの対応をさせるものを作りたいのですが、
下記のようにしたとき、どうしてもうまくいかないところがあります。
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");
}
No.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) ということでした。
残りですが、2)は提示して頂いたif文に若干付け加えをして、問題なくいけました。
atoi()ですが、使うのをやめてstrtol()という関数を使って動作させることにしました。こちらの方がしっくりくるようです。
結局は質問で提示したコードとは大幅に違うものが出来ました(まだ途中です)が、回答者さま達の忠告(アドバイス)を読んで、見直すところが多々ありました。
色々に答えてくださりありがとうございました。
No.3
- 回答日時:
#1で色々言われてますがもう一点。
・文字列(char配列)を扱う時には終端文字分まで確保しなければならず、また終端設定は基本的に自力で行わなければならないが、その辺りがすっぽり抜けている
これでatoi(ID)が期待通りに動いているのは奇跡というかただのマグレです。
なお2についてはsscanf()を使えば比較的楽に出来るでしょう。
この回答への補足
終端設定と言うと…'\0'のことでしょうか?
最後にいれなければと思っているのですが、そこまで考えていられなくて…
>なお2についてはsscanf()を使えば比較的楽に出来るでしょう。
それは思ったのですが、どうやらscanf()系が使えないコンパイラみたいなので、別の方法を探しています。
ちなみに、ccscのpiccコンパイラです。
No.2
- 回答日時:
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");
}
No.1
- 回答日時:
> 入力された文字列を判断して、それぞれの対応をさせるものを作りたい
どんな入力に対してどんな結果を得たいのかが質問文からは分かりません。補足をお願いします。
> (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]がそれにあたります。書き間違いでした。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# LU分解法のピボッティングについて(C言語/gcc-9) 3 2022/07/11 23:10
- JavaScript フォームが空欄の時にフォームの外をクリックすると、エラーが出るコードを調べています。 1 2023/06/25 11:51
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
sscanfとscanfの違いがよくわか...
-
CStringのFindで文字列検索を行...
-
fgets関数を使用したときの文字...
-
C言語 空白の行(改行のみ)が...
-
charと%c , %s の関係について
-
1行の文字列を時間差で表示する...
-
ブランクのチェック
-
エディットボックスに入力され...
-
反転した数値を表示させるやり方
-
C言語、単語ごとに改行したい
-
C言語のステップ数をカウントす...
-
itoaわかりません
-
strstrを利用しない文字列検索...
-
小文字のみを数える方法
-
C言語 ポインタを使用した文字...
-
データ数値を16進文字列でprint...
-
16進数の文字列
-
スペースで区切って数字を入力
-
プログラミング シーザー暗号 ...
-
「an=(n-1)/(n+1)のときlim[n→∞...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CStringのFindで文字列検索を行...
-
sscanfとscanfの違いがよくわか...
-
反転した数値を表示させるやり方
-
C言語のステップ数をカウントす...
-
Cで「大文字、小文字の判定」は...
-
charと%c , %s の関係について
-
ある文字列で2回目3回目に出現...
-
itoaわかりません
-
fgets関数を使用したときの文字...
-
fgetsで拾われる改行文字を削除...
-
C言語で16進数文字列から16進数...
-
CStringについて
-
文字列中に含まれる文字の個数...
-
strstrを利用しない文字列検索...
-
文の意味
-
エディットボックスに入力され...
-
文字列の途中に「0」がある場...
-
C++
-
putsとputcharの違い?
-
教えていただけませんか?C言語...
おすすめ情報