題目的修正 我拋棄了原題中“其中a, b, c, d是一個0-9的整數”這樣的前提條件,因為這種限制毫無必要。只假設a, b, c, d是十進制整數形式的字符序列。 我也不清楚這種題目應該如何結束輸入。下面的代碼假設在沒有正確輸入完整的運算式時結束。 數據結構 typedef struct { int numer ; //分子 int denom ; //分母 } frac_t ;//分數類型 數據 一共需要三個變量,兩個記錄分數,一個記錄運算符。 #include <stdio.h> int main( void ) { frac_t frc1 , frc2 ;//兩個操作數 char op ; //運算符 return 0; } 復制代碼 總體結構 #define FAIL 0 int main( void ) { frac_t frc1 , frc2 ;//兩個分數 char op ; //運算符 while ( input_exp( &frc1 , &op , &frc2 ) != FAIL )//輸入算式 { //計算,輸出 } return 0; } input_exp()的實現 int input_exp( frac_t * , char * , frac_t * ); int input_frac( frac_t * ); int input_exp( frac_t * p_f1 , char * p_o , frac_t * p_f2 ) { if ( input_frac( p_f1 ) != 2 ) return FAIL ; if ( scanf(" %c " , p_o ) != 1 ) return FAIL ; switch ( * p_o ) { default : return FAIL ;//不是加、減法 case '+': case '-': ; } if ( input_frac( p_f2 ) != 2 ) return FAIL ; return !FAIL ; } int input_frac( frac_t * p_f ) { return scanf("%d / %d" , &p_f->numer , &p_f->denom ); } //計算,輸出部分 首先排除無意義的輸入 if ( frc1.denom == 0 || frc2.denom == 0 ) //無意義的輸入 { puts( "分數無意義" ); continue ; } 把減法變為加法 switch ( op ) { case '-':frc2.numer = - frc2.numer ;//把減法化為加法 case '+':add_to( &frc1 , &frc2 ); //計算結果放在frc1中 break ; } 最後輸出結果 output( frc1 ); putchar( '\n' ); 完整的代碼: /* 分數的加減法 編寫一個C程序,實現兩個分數的加減法 輸入:輸入包含多行數據 每行數據的格式是 a/boc/d 。 其中a, b, c, d為十進制整數,o是運算符"+"或者"-"。 輸出:對於輸入數據的每一行輸出兩個分數的運算結果。 注意結果應符合書寫習慣,沒有多余的符號、分子、分母,並且化簡至最簡分數 樣例輸入: 1/8+3/8 1/4-1/2 1/3-1/3 輸出: 1/2 -1/4 0 */ #include <stdio.h> #include <stdlib.h> typedef struct { int numer ; //分子 int denom ; //分母 } frac_t ;//分數類型 #define FAIL 0 int input_exp( frac_t * , char * , frac_t * ); int input_frac( frac_t * ); void add_to( frac_t * , frac_t const * ); int find_lcm( int , int ); int find_gcd( int , int ); void reduce( frac_t * ); void output( frac_t ); int main( void ) { frac_t frc1 , frc2 ;//兩個分數 char op ; //運算符 while ( input_exp( &frc1 , &op , &frc2 ) != FAIL )//輸入算式 { //計算,輸出 if ( frc1.denom == 0 || frc2.denom == 0 ) //無意義的輸入 { puts( "分數無意義" ); continue ; } switch ( op ) { case '-':frc2.numer = - frc2.numer ;//把減法化為加法 case '+':add_to( &frc1 , &frc2 ); //計算結果放在frc1中 break ; } output( frc1 ); putchar( '\n' ); } return 0; } void output( frac_t fr ) { if ( fr.numer < 0 ) { putchar( '-' ); fr.numer = - fr.numer ; } if ( fr.denom == 1 ) { printf( "%d" , fr.numer ); return ; } printf( "%d/%d" , fr.numer , fr.denom ); } void reduce( frac_t * p_f ) { int gcd = find_gcd( abs( p_f->numer ) , abs( p_f->denom ) ) ; p_f->denom /= gcd ; p_f->numer /= gcd ; } int find_gcd( int m , int n ) { int t ; return (t = m % n) == 0 ? n : find_gcd( n , t ); } int find_lcm( int m , int n ) { return m / find_gcd( m , n ) * n ; } void add_to( frac_t * p_f1 , frac_t const * p_f2 ) { int lcm = find_lcm( abs( p_f1->denom ) , abs( p_f2->denom ) ); p_f1->numer = lcm / p_f1->denom * p_f1->numer + lcm / p_f2->denom * p_f2->numer ; p_f1->denom = lcm ; //分母總是正的 reduce( p_f1 ); //約分 } int input_frac( frac_t * p_f ) { return scanf( "%d / %d" , &p_f->numer , &p_f->denom ); } int input_exp( frac_t * p_f1 , char * p_o , frac_t * p_f2 ) { if ( input_frac( p_f1 ) != 2 ) return FAIL ; if ( scanf( " %c " , p_o ) != 1 ) return FAIL ; switch ( * p_o ) { default : return FAIL ;//不是加、減法 case '+': case '-': ; } if ( input_frac( p_f2 ) != 2 ) return FAIL ; return !FAIL ; }