- ベストアンサー
入力された2つの整数の差を絶対値を出力するプログラム
2整数の差を絶対値を出力するプログラムをつくりました. 入力される数値は、正数の場合は最大8桁まで有効とし、9桁目以降を無視、負数の場合は '-'を含め、最大9桁まで有効とし,10桁目以降を無視するようにしたい。 2番目の数値入力で9桁以降に数字以外の文字を入力すると,うまく動きません.なぜ動かないかとどのように直したらよいか教えてください. お願いします. #include <stdio.h> #include <stdlib.h> #define BUFFERSIZE 10 #define PLUS_MAX 8 #define MINUS_MAX 9 #define C_NULL ('\0') #define RC_OK 0 #define RC_ND -1 #define RC_ID -2 #define RC_MD -3 int absolute( int n1, int n2 ) ; main() { char n[ 2 ][ BUFFERSIZE ]; int i ; int a[ 2 ] ; int ab ; int count ; int n_pos ; char c ; for( i = 0 ; i < 2 ; i ++ ){ printf( "%d番目の数値 :", i + 1 ) ; for( count = 0 ; count <= BUFFERSIZE ; count ++ ){ c = getchar() ; if( c >= '0' && c <= '9' || count == 0 && c == '-' ){ n[i][ count ] = c ; continue ; } if( c == '\n' ) break ; printf( "Error!\n" ) ; return( RC_ID ) ; } if( count == 0 ){ printf("Error!\n"); return( RC_ND ); } else if( n[ i ][ 0 ] == '-' && count < 2 ){ printf("Error!\n"); return( RC_ID ) ; } if( n[ i ][ 0 ] == '-' && count > MINUS_MAX ){ n_pos = MINUS_MAX ; }else{ if( count > PLUS_MAX ){ n_pos = PLUS_MAX ; }else{ n_pos = count ; } } n[ i ][ n_pos ] = '\0' ; a[ i ] = atoi( n[ i ] ) ; } ab = absolute( a[ 0 ], a[ 1 ] ) ; printf( "絶対値は %d \n", ab ) ; return( RC_OK ); } int absolute(int n1, int n2) { int i ; i = n1 - n2 ; return i >= 0 ? i : -i ; }
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
★ソースを覗いた感想は main 関数が長すぎます。 ・上手く動かないようですが、バグを探る前に main 関数のソースを整理します。 下に main 関数のサンプルを載せます。→これを元に main 関数とサブ関数を作ります。 ・入力部は『MyUserInput』関数にお任せしています。→main 関数に記述しません。 この関数は1つの整数文字列を入力してから、その文字列を整数変換して引数 input へ代入します。 戻り値は、正常(RC_OK)、エラー(RC_ND,RC_ID,RC_MD)を返します。 この戻り値は、main 関数で受け取って処理します。→エラーメッセージも main 関数の担当にします。 サンプル: int main( void ) { int a[ 2 ]; int i, ret; for ( i = 0 ; i < 2 ; i ++ ){ printf( "%d番目の数値 :", i + 1 ) ; if ( (ret = MyUserInput(&a[i])) != RC_OK ){ printf( "Error!\n" ); return( ret ); } } printf( "絶対値は %d \n", absolute(a[0],a[1]) ); ←『ab』に代入しなくても可能 return( RC_OK ); } /* 1つの整数文字列を入力(整数変換も含む) */ int MyUserInput( int *input ) { char n[ BUFFERSIZE + 1 ]; int c; ←『char』ではなくて int 型で宣言(EOF=-1 が戻る事もあるので) int count; for ( count = 0 ; count < BUFFERSIZE ; ){ ←回答者 No.1 さんのアドバイスより( <= ではありません) if ( (c = getchar()) == EOF ){ break; } if ( c == '\n' ){ break; } if ( isdigit(c) ){ ←'0'~'9'ならば『真』 n[ count++ ] = (char)c; ←キャストが必要! } else if ( c == '-' ){ if ( count != 0 ){ return( エラーを返す ); ←最初以外の『-』入力エラー } n[ count++ ] = (char)c; ←キャストが必要! } else{ return( エラーを返す ); ←数字と『-』以外の入力エラー } } if ( count == 0 ){ return( RC_ND ); ←入力されていないエラー } n[ count ] = '\0'; ←入力の最後の NULL 文字 if ( n[0] == '-' ){ ←先頭が『-』文字 n[ MINUS_MAX ] = '\0'; ←負ならば 10 桁以降を無視 } else{ n[ PLUS_MAX ] = '\0'; ←正ならば 9 桁以降を無視 } *input = atoi( n ); ←整数変換して input にセット return( RC_OK ); ←この関数の戻り値は(RC_OK,RC_ND,RC_ID,RC_MD)を返す } 最後に: ・main 関数とサブ関数の作り方も含めて『サンプル』を掲示してみました。 ・これからプログラミングしていくにあたり、main 関数はあまり長くならないように気をつけて下さい。 またサブ関数に出来る場合は、関数機能を整理してから作成して下さい。→今回は整数の入力のみを 担当する『MyUserInput』関数がそのサブ関数です。 ・あとサブ関数のエラーは『戻り値』として main 関数に戻して、main 関数の中で『printf("Error!\n");』 などのエラー処理を行います。→この方がすっきりとして分かりやすくなります。→バグにならずにすむ。 ・上記の注意点として『BUFFERSIZE』定数は『9』にして下さい。 『for』文のときに『9』でないとまずいから。 宣言では『char n[ BUFFERSIZE + 1 ];』と『+1』していますので大丈夫です。 ・サブ関数『absolute』には問題はありません。 ・以上。おわり。→上記のサンプルを参考に今回の問題点を整理してみましょう。
その他の回答 (2)
- maronii_now
- ベストアンサー率0% (0/8)
これでどうでしょうか? #include <stdio.h> #include <stdlib.h> #define BUFFERSIZE 10 #define PLUS_MAX 8 #define MINUS_MAX 9 #define C_NULL ('\0') #define RC_OK 0 #define RC_ND -1 #define RC_ID -2 #define RC_MD -3 int absolute( int n1, int n2 ) ; main() { char n[ 2 ][ BUFFERSIZE ]; int i ; int a[ 2 ] ; int ab ; int count ; int n_pos ; char c ; // 初期化 memset( n , 0x00 , sizeof(n) ); for( i = 0 ; i < 2 ; i ++ ) { printf( "%d番目の数値 :", i + 1 ) ; for( count = 0 ; count <= BUFFERSIZE ; count ++ ) { c = getchar() ; //if( c >= '0' && c <= '9' || count == 0 && c == '-' ){ //{ // n[i][ count ] = c ; // continue ; //} // マイナスの符号の時 if( count == 0 && c == '-' ) { n[i][ count ] = c ; continue ; } // 負のとき else if( n[i][0]=='-' ) { if( c >= '0' && c <= '9' ) { n[i][ count ] = c ; continue ; } } // 正のとき else if( n[i][0]!='-' ) { // 9桁目以降は無視なので if( count>=8 ) continue; else if( c >= '0' && c <= '9' ) { n[i][ count ] = c ; continue ; } } if( c == '\n' ) break ; printf( "Error!\n" ) ; return( RC_ID ) ; } if( count == 0 ) { printf("Error!\n"); return( RC_ND ); } else if( n[ i ][ 0 ] == '-' && count < 2 ) { printf("Error!\n"); return( RC_ID ) ; } if( n[ i ][ 0 ] == '-' && count > MINUS_MAX ) { n_pos = MINUS_MAX ; } else { if( count > PLUS_MAX ) { n_pos = PLUS_MAX ; } else { n_pos = count ; } } n[ i ][ n_pos ] = '\0' ; a[ i ] = atoi( n[ i ] ) ; } ab = absolute( a[ 0 ], a[ 1 ] ) ; printf( "絶対値は %d \n", ab ) ; return( RC_OK ); } int absolute(int n1, int n2) { int i ; i = n1 - n2 ; return i >= 0 ? i : -i ; }
- php504
- ベストアンサー率42% (926/2160)
気づいた点を一つ for( count = 0 ; count <= BUFFERSIZE ; count ++ ){ これだと(BUFFERSIZE + 1)回ループします