
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 ;
}
No.2ベストアンサー
- 回答日時:
★ソースを覗いた感想は 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』には問題はありません。
・以上。おわり。→上記のサンプルを参考に今回の問題点を整理してみましょう。
No.3
- 回答日時:
これでどうでしょうか?
#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 ;
}
No.1
- 回答日時:
気づいた点を一つ
for( count = 0 ; count <= BUFFERSIZE ; count ++ ){
これだと(BUFFERSIZE + 1)回ループします
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ラップ関数とはどんなものですか?
-
C言語での引数の省略方法
-
複数桁10進数の*桁目だけを抽出...
-
時間のパルスを作りたい。
-
std::set<int> で、ある値が何...
-
乱数について2
-
エラー 添字が付けられた値が、...
-
#define _CRT_SECURE_NO_WARNIN...
-
C言語 エラーの原因がわからな...
-
配列 平均値と分散値
-
C言語のポインタ配列について
-
(int *)の意味
-
「指定されたキャストは有効で...
-
windows-findstrの正規表現を使...
-
わかる方いませんか?
-
構造体の勉強中です 合計点の高...
-
双子の素数
-
{x = x>y ? x:y; return x;}
-
C++ ポインタ初級
-
最大値(c++)
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「指定されたキャストは有効で...
-
C言語での引数の省略方法
-
複数桁10進数の*桁目だけを抽出...
-
C言語 エラーの原因がわからな...
-
#define _CRT_SECURE_NO_WARNIN...
-
ラップ関数とはどんなものですか?
-
【C++】関数ポインタの使い方
-
実数の整数部,小数部の取得
-
int型の変数値をバイト列として...
-
std::set<int> で、ある値が何...
-
PowerShellがうまくいかない
-
(int *)の意味
-
CStringの配列要素を関数で受け...
-
ColorをRGBで指定する方法
-
「{ } で囲むだけ」は正しい?
-
acceptをalarmでタイムアウトさ...
-
if と配列の組み合わせ
-
read関数をノンブロッキングで...
-
(マルチスレッド)_beginthrea...
-
int16_t の _t は何?
おすすめ情報