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

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

A 回答 (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』には問題はありません。
・以上。おわり。→上記のサンプルを参考に今回の問題点を整理してみましょう。
    • good
    • 0

これでどうでしょうか?



#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 ;
}
    • good
    • 0

気づいた点を一つ


for( count = 0 ; count <= BUFFERSIZE ; count ++ ){
これだと(BUFFERSIZE + 1)回ループします
    • good
    • 0

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