我拋棄了原題中「其中a, b, c, d是一個0-9的整數」這樣的前提條件,由於這種限制毫無必要。只假設a, b, c, d是十進制整數形式的字符序列。html
我也不清楚這種題目應該如何結束輸入。下面的代碼假設在沒有正確輸入完整的運算式時結束。數據結構
typedef struct { int numer ; //分子 int denom ; //分母 } frac_t ;//分數類型
一共須要三個變量,兩個記錄分數,一個記錄運算符。spa
#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; }
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 )//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 ); }
首先排除無心義的輸入 code
if ( frc1.denom == 0 || frc2.denom == 0 ) //無心義的輸入 { puts( "分數無心義" ); continue ; }
把減法變爲加法htm
switch ( op ) { case '-':frc2.numer = - frc2.numer ;//把減法化爲加法 case '+':add_to( &frc1 , &frc2 ); //計算結果放在frc1中 break ; }
最後輸出結果blog
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 做者:薛非 出處:http://www.cnblogs.com/pmer/ 「C語言初學者代碼中的常見錯誤與瑕疵」系列博文 */ #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 )//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 ; }