入力された数字を数値に変換するプログラムを作ったのですが、うまくいきません。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
unsigned long long atollu(char[16]);
void main(void){
unsigned long long input;
char str[16];
char test[16] = "123456789012345";
int i,j=1;
//atollu の動作確認・・・(1)
printf("atollu test:%llu\n\n",atollu(test) );
//入力
NG:
printf("%d回目 数値を入力(1~100000000000000 終了:exit)>",j);
gets(str);
input = atollu(str);
//str と atollu(str) の確認
printf("%s %llu\n\n",str,atollu(str));
//exitと入力すると終了・・・(2)
if(strcmp(str, "exit") == 0){
exit(0);
}
//数字以外がないか確認・・・(3)
else {
for( i=0; i<=15; i++){
if(isdigit(str[i]) == 0){
printf("NG\n");
for( i=0; i<=16; i++){
str[i]='\0';
}
printf("moji\n");
j++;
goto NG;
}
}
}
//範囲外
if(input>100000000000000 || input==0){
printf("NG\n");
printf("hani\n");
j++;
goto NG;
}
printf("\n入力値は% llu",input );
}
unsigned long long atollu(char str[16]){
unsigned long long t=0;
int i,n;
n = strlen(str) - 1;
for( i=0; i<=15; i++){
if(str[i] == '\0'){ str[i] = 0;}
else { t = t + (str[i] - '0') * pow(10.0,n-i);}
}
str[16] = '\0';
return t;
}
/*
数字を数値に変換する関数atolluは自分で作りました。
これの動作は(1)でちゃんとした値が出ているのでうまくできているようです。
(2)も"exit"と入力すれば終了するのでうまくいっています。
また、例えば "12" と入力したとき
12 9
NG
moji
表示されますが、二回目以降は
12 12
NG
moji
となり、atollu(str)はうまく出力されている一方で、最後に「moji」と出てきているので、(3)でうまくいっていないようです。
どう直すべきなのか見当もつかないので困っています。
よろしくお願いします。
No.2
- 回答日時:
ご質問に対する直接的な回答ではないのですが、私の個人的な意見を述べさせていただきたいと思います。
質問内容のchar test[16]を見ると整数値を想定しているようなので、
整数値に限ってお話させていただきます。
おそらく想定している環境はアスキーコードで入力されることを
想定していると解釈いたしました。
そこで、アスキーコード表ではいわゆる数字の0~9は0~9という数字で定義されており、文字列の0~9は48~57という数字で定義されています。
そこで、以下のようなプログラムでは目的の動作を果たせないのでしょうか?
int main( ) {
int i ;
int output = 0 ;
char str[ 11 ] = { '\0' } ;
printf( "整数値で10桁まで入力できます : " ) ;
scanf( "%s", str ) ;
for( i = 0 ; str[ i ] != '\0' ; i ++ ) {
if( ( str[ i ] - 48 ) > 9 )
return 0 ;
if( ( str[ i ] - 48 ) < 0 )
return 0 ;
}
for( i = 0 ; str[ i ] != '\0' ; i ++ )
output = output * 10 + ( str[ i ] - 48 ) ;
printf( "%d\n", output ) ;
}
ひょっとするとyata16さんが意図している動作と違うかもしれませんが、参考までに意見させていただきました。
また、上のプログラムはscanfの特性を受けますので、間にスペース等が入ると意図しない動作になる可能性がありますので、注意してください。
コンセプトとして"scanf"を使わないようにしていたので、若干違いますが、本質的には同じです。動作も大丈夫でした。
ありがとうございました。
No.1ベストアンサー
- 回答日時:
★条件式がおかしい。
>//数字以外がないか確認・・・(3)
この場所。
間違い⇒for( i=0; i<=15; i++){
正しい⇒for( i=0; str[i] != '\0'; i++){
※15文字と決め付けない方が良いでしょう。
・for文中のfor文で『i=0』にしているので正しく数字以外を判定できない。
str配列は gets 関数で上書きされるため明示的に初期化しなくて良い。
よってfor文中のfor文処理はいらない。削除すべき。
for ( i = 0 ; str[i] != '\0' ; i++ ){
if ( !isdigit(str[i]) ){
printf("NG\n");
printf("moji\n");
j++;
goto NG;
}
}
これだけでよい。
・atollu関数の条件式もおかしい(安全でない)
間違い⇒for( i=0; i<=15; i++){
正しい⇒for( i=0; str[i] != '\0' ; i++){
※ここも15文字と決め付けない方が…。
間違い⇒str[16] = '\0';
正しい⇒str[15] = '\0';
※これは完全に良くありません。
※引数がstr[16]なのでstr[15]までしかアクセスしてはいけません。
※そもそもこの処理は必要なのですか?
・次の処理は意味がありません。
>if(str[i] == '\0'){
> str[i] = 0;
>}
'\0'も 0 も同じ値ですよ。
※ソース上での表現の違いだけです。
※『0』も『'\0'』も『0x00』も同じ値(ゼロ)です。
サンプル:
unsigned long long atollu( char str[] )
{
unsigned long long t = 0;
int i;
//for ( i = 0 ; isdigit(str[i]) ; i++ ){
for ( i = 0 ; str[i] != '\0' ; i++ ){
t = (t * 10) + (str[i] - '0');
}
return t;
}
※pow関数を使わなくても出来ます。
※条件式の『str[i] != '\0'』よりも『isdigit(str[i])』の方が良い。
なるほど、すごく勉強になりました。
よく考えたら配列の最後まで見なくても空の部分まで見ればいいのは当たり前ですね・・・。
まだまだ勉強不足でした。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# str[j++]の意味 2 2022/08/30 16:20
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- Excel(エクセル) 2つのVBAを一緒にしたら機能しなくなりました(エクセル) 7 2022/06/02 12:41
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- その他(プログラミング・Web制作) 物理の斜方投射で目盛りに数値を入れたい 2 2023/05/27 06:32
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
10個出力で改行したいのですが...
-
strcmp
-
CTRL+Dでループを抜けるには
-
4の倍数を論理演算で表す。。
-
【C言語教えてください】sin波...
-
scanfに文字が入力されたときに...
-
ガウスの消去法、後退代入について
-
C言語プログラミング
-
defineで定数が置き換えられな...
-
printf で二進表示を行いたい。
-
c言語でAからZまでを表示する...
-
分数を表示するプログラム(長...
-
switch分のケースを範囲数?に...
-
カレンダーのプログラムについて
-
C言語初心者です。次の問題で質...
-
C言語です
-
じゃんけんゲームの応用
-
BMI値から体型を判定するプログ...
-
(C言語)めちゃくちゃな値にな...
-
なぜgccはstdio.hをインクルー...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語について
-
printf で二進表示を行いたい。
-
cshの文字列操作(0埋め)
-
10個出力で改行したいのですが...
-
コンパイルエラーについて
-
テキストカーソル位置の取得
-
strcmp
-
unsigned int型について
-
c言語でAからZまでを表示する...
-
printf( " %2d", p * q );
-
コマンドラインに出力した文字...
-
printfの出力内の文字をdefine...
-
ホームページをC言語で作りたい...
-
コマンドプロンプトがすぐ消える
-
小数点切捨て表示
-
【C言語教えてください】sin波...
-
switch分のケースを範囲数?に...
-
二つの整数値の大小比較
-
4の倍数を論理演算で表す。。
-
defineで定数が置き換えられな...
おすすめ情報