C program: working time

Posted on 2007-11-17 04:04  QT_pixy  阅读(319)  评论(0)    收藏  举报

这个程序功能很简单,但具体要求非常多。考虑到程序的严谨性所以要针对所有可能出现的情况进行处理。第一次进行test cases测试的时候一大半的test cases都没有通过,进行分析修改后以下程序通过所有的test cases. 因为限制只能用部分C的function,所以要求较高的逻辑思维能力。
这个程序看似很难看,用了很多个相套的if statement.
如果需要具体的程序说明文档和test cases请与我联系。



#include <stdio.h>
#include 
<limits.h>

/* Specify the priority of error message */
#define INVALID_SYNTAX 5;
#define OVERFLOW 4;
#define IMPOSSIBLE_TIME 3;
#define END_BEFORE_START 2;
#define AMBIGUOUS 1;

int main(void)
{
    
int c;           /* read a character one by one and save it into c */
    
int length;      /* length of the number */
    
char s[1000];    /* the string used to save the input number */ 
    unsigned 
long long start_time, end_time;     /* variables used to store the atart time and end time */
    
int message_number;        /* store the defined message number, decide which message should be displayed */
    
int first_ambi, second_ambi;          /* check if the first and second numbers are ambiguous */

    
while((c = getchar()) != EOF)
    
{
        length 
= 0;                        /************************/
        start_time 
= 0;                    /*                      */
        end_time 
= 0;                      /* initialize variables */
        message_number 
= 0;                /*                      */
        first_ambi 
= 1;                    /*                      */
        second_ambi 
= 1;                   /************************/

        
while(c == ' ' || c == '\t' || c == '\0')
            c 
= getchar();          /* remove the leading space, tab or \0 */
            
            
        
/* if the first input character is a digit */
        
if(c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9')
        

            s[length] 
= c;
            length
++;

            
int check = 1;
            
/* get the first input number */
            
while(check != 0  && (c = getchar()) != EOF)
            
{
                
if(c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9'
                
{
                    s[length] 
= c;
                    length
++;
                }

                
else
                   check 
= 0;
            }


            
int i;
            
/* convert the string to a decimal number */
            
for(i = 0; i < length; i++
            
{
                unsigned 
long long temp_number = s[i] - 48;

                
if(i == length - 1)
                    start_time 
= start_time + s[i] - 48;
                
else
                

                    
int x;
                    
for(x = i; x < length - 1; x++)
                        temp_number 
= temp_number * 10;
                    start_time 
= temp_number + start_time;
                }
 
            }


            
/* check if the number overflow */
            
if(start_time > UINT_MAX)
            
{
                
if(message_number < 4)
                    message_number 
= OVERFLOW;
            }


            
/* If the number ends with white space, which means no "am" or "pm".
               We have to check if the number is from 0 to 23 
*/

            
if(c == ' ' || c == '\t' || c == '\0'
            
{
                  
if(start_time != 0 && start_time <= 12)
                      first_ambi 
= 0;
                      
                
if(start_time > 24)
                
{
                    
if(message_number < 3)
                        message_number 
= IMPOSSIBLE_TIME; 
                }

                
                
if(start_time == 12)
                    start_time 
= 0;         /*12 can be 12am and 12pm, now we let start_time be 12am */
            }

            
/* when the number ends with "am" */
            
else if(c == 'a')
            
{
                
if((c = getchar()) == 'm')
                
{   
                    
/* check if the number which ends with "am" is greater than 12 or equals to 0 */               
                    
if(start_time > 12 || start_time == 0)
                    
{
                        
if(message_number < 3)
                            message_number 
= IMPOSSIBLE_TIME;
                    }

                    
/* 12am means midnight */
                    
if(start_time == 12)
                        start_time 
= 0;
                }

                
else
                    message_number 
= INVALID_SYNTAX;
            }

            
/* when the number ends with "pm" */
            
else if(c == 'p')
            
{
                
if((c = getchar()) == 'm'
                
{
                    
/* check if the number which ends with "pm" is greater than 12 or equals to 0 */ 
                    
if(start_time > 12 || start_time == 0)
                    
{    
                        
if(message_number < 3)
                            message_number 
= IMPOSSIBLE_TIME; 
                    }

                    
/* 12pm means noon */
                    
else if(start_time == 12)
                        ;
                    
else
                        start_time 
= start_time + 12;
                }

                
else 
                    message_number 
= INVALID_SYNTAX;
            }

            
else
                message_number 
= INVALID_SYNTAX;
        }

        
/* if the first input character is 'n', we want to check if it is followed by "oon" */
        
else if(c == 'n')
        
{
            
if((c = getchar()) == 'o'
            
{
                
if((c = getchar()) == 'o')
                
{
                    
if((c = getchar()) == 'n')
                    
{
                        
if((c = getchar()) == '\0' || c == ' ' || c == '\t')  /* the end of string "noon" */
                        
{
                            start_time 
= 12;
                        }

                        
else
                            message_number 
= INVALID_SYNTAX;
                    }
 
                    
else
                        message_number 
= INVALID_SYNTAX;
                }

                
else
                    message_number 
= INVALID_SYNTAX;
            }

            
else 
                message_number 
= INVALID_SYNTAX;
        }

        
/* if the first input character is 'm', we want to check if it is followed by "idnight" */
        
else if(c == 'm')
        
{
            
if((c = getchar()) == 'i')
            
{
                
if((c = getchar()) == 'd'
                
{
                    
if((c = getchar()) == 'n')
                    
{
                        
if((c = getchar()) == 'i')
                        
{
                            
if((c = getchar()) == 'g'
                            
{
                                
if((c = getchar()) == 'h')
                                
{
                                    
if((c = getchar()) == 't')
                                    

                                        
if((c = getchar()) == '\0' || c == ' ' || c == '\t'/* the end of string "midnight" */
                                        
{
                                            start_time 
= 0
                                            first_ambi 
= 1;
                                            
                                        }

                                        
else
                                            message_number 
= INVALID_SYNTAX;
                                    }

                                    
else 
                                        message_number 
= INVALID_SYNTAX;
                                }

                                
else
                                    message_number 
= INVALID_SYNTAX; 
                            }

                            
else
                                message_number 
= INVALID_SYNTAX;
                        }

                        
else
                            message_number 
= INVALID_SYNTAX; 
                    }

                    
else
                        message_number 
= INVALID_SYNTAX;
                }

                
else
                    message_number 
= INVALID_SYNTAX;
            }
 
            
else
                message_number 
= INVALID_SYNTAX;
        }

        
else
            message_number 
= INVALID_SYNTAX;


        length 
= 0;    /* initialize variable */
        
if(c != '\n')
        

            
/* check if there is no white space after the start time */
            
if((c == 'm'||== 't'||== 'n'&& (c = getchar()) != ' ' && c != '\t' && c != '\0')
                message_number 
= INVALID_SYNTAX; 
            
/* remove the white space after the start time */
            
while(c == ' ' || c == '\t' || c == '\0')
                c 
= getchar();
        }

        
/* if the second input character is a digit */
        
if(c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9'
        
{
            s[length] 
= c;
            length
++;

            
int check = 1;
            
/* get the second input number */
            
while(check != 0  && (c = getchar()) != EOF)
            
{
                
if(c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9'
                
{
                    s[length] 
= c;
                    length
++;
                }

                
else
                    check 
= 0;
            }


            
int i;
            
/* convert the string to a decimal number */
            
for(i = 0; i < length; i++
            
{
                unsigned 
long long temp_number = s[i] - 48;

                
if(i == length - 1)
                    end_time 
= end_time + s[i] - 48;
                
else
                

                    
int x;
                    
for(x = i; x < length - 1; x++)
                        temp_number 
= temp_number * 10;
                end_time 
= temp_number + end_time;
                }
 
            }

 
            
/* check if the number overflow */
            
if(end_time > UINT_MAX)
            
{
                
if(message_number < 4)
                    message_number 
= OVERFLOW;
            }

            
/* If the number ends with white space, which means no "am" or "pm".
               We have to check if the number is from 0 to 23 
*/

            
if(c == ' ' || c == '\t' || c == '\n' || c == '\0'
            
{   
                  
if(end_time <= 12)
                      second_ambi 
= 0;
                  
                
if(end_time > 24)
                
{
                    
if(message_number < 3)
                        message_number 
= IMPOSSIBLE_TIME; 
                }

            }

            
/* when the number ends with "am" */
            
else if(c == 'a')
            
{
                
if((c = getchar()) == 'm')
                
{
                    
/* check if the number which ends with "am" is greater than 12 or equals to 0 */ 
                    
if(end_time > 12 || end_time == 0
                    
{
                        
if(message_number < 3)
                            message_number 
= IMPOSSIBLE_TIME;
                    }

                    
/* 12am means midnight */
                    
if(end_time == 12)
                    
{
                        end_time 
= 24;
                        second_ambi 
= 0;
                    }
 
                }

                
else
                    message_number 
= INVALID_SYNTAX;
            }

            
/* when the number ends with "pm" */
            
else if(c == 'p')
            
{
                
if((c = getchar()) == 'm'
                
{
                    
/* check if the number which ends with "pm" is greater than 12 or equals to 0 */
                    
if(end_time > 12 || end_time == 0)
                    
{
                        
if(message_number < 3)
                            message_number 
= IMPOSSIBLE_TIME; 
                    }

                    
/* 12pm means noon */
                    
else if(end_time == 12)
                        ;
                    
else
                        end_time 
= end_time + 12;
                }

                
else 
                    message_number 
= INVALID_SYNTAX;
            }

            
else
                message_number 
= INVALID_SYNTAX;
        }

        
/* if the first input character is 'n', we want to check if it is followed by "oon" */
        
else if(c == 'n')
        
{
            
if((c = getchar()) == 'o'
            
{
                
if((c = getchar()) == 'o')
                
{
                    
if((c = getchar()) == 'n')
                    
{
                        
if((c = getchar()) == '\0' || c == ' ' || c == '\t' || c == '\n')  /* the end of string "noon" */
                        
{
                            end_time 
= 12;
                        }

                        
else
                            message_number 
= INVALID_SYNTAX;
                    }
 
                    
else
                        message_number 
= INVALID_SYNTAX;
                }

                
else
                    message_number 
= INVALID_SYNTAX;
            }

            
else 
                message_number 
= INVALID_SYNTAX;
        }

        
/* if the first input character is 'm', we want to check if it is followed by "idnight" */
        
else if(c == 'm')
        
{
            
if((c = getchar()) == 'i')
            
{
                
if((c = getchar()) == 'd'
                
{
                    
if((c = getchar()) == 'n')
                    
{
                        
if((c = getchar()) == 'i')
                        
{
                            
if((c = getchar()) == 'g'
                            
{
                                
if((c = getchar()) == 'h')
                                
{
                                    
if((c = getchar()) == 't')
                                    

                                        
if((c = getchar()) == '\0' || c == ' ' || c == '\t' || c == '\n'/* the end of string "midnight" */
                                        
{
                                            end_time 
= 24;
                                            second_ambi 
= 0;
                                             
                                        }

                                        
else
                                            message_number 
= INVALID_SYNTAX;
                                    }

                                    
else 
                                        message_number 
= INVALID_SYNTAX;
                                }

                                
else
                                    message_number 
= INVALID_SYNTAX; 
                            }

                            
else
                                message_number 
= INVALID_SYNTAX;
                        }

                        
else
                            message_number 
= INVALID_SYNTAX; 
                    }

                    
else
                        message_number 
= INVALID_SYNTAX;
                }

                
else
                    message_number 
= INVALID_SYNTAX;
            }
 
            
else
                message_number 
= INVALID_SYNTAX;
        }

        
else
            message_number 
= INVALID_SYNTAX;

        
/* if the two times are definite, we do not have to check if they are ambiguous.
           Just check if the time end before start
*/

        
if((first_ambi == 1 || start_time > 12&& (second_ambi == 1 || (end_time > 12 && end_time != 24))) 
        
{
            
if(end_time < start_time && message_number < 2)
                message_number 
= END_BEFORE_START;
        }

        
/* if the first time is definite but the second time is ambiguous,
           the time interval may be ambiguous 
*/

           
        
else if((first_ambi == 1 || start_time >= 12&& (second_ambi == 0 && (end_time <= 12 || end_time == 24))) 
        
{
              
if(start_time == 0 && (end_time == 0 || end_time == 24&& message_number < 1)
                message_number 
= AMBIGUOUS;

            
if((start_time < end_time) && end_time != 24)
            
{
                
if(message_number < 1)
                    message_number 
= AMBIGUOUS;
            }

            
else
            

                
if(end_time <= 12)
                    end_time 
= end_time + 12;
                
if(end_time < start_time && message_number < 2)
                    message_number 
= END_BEFORE_START;
            }

        }

        
/* if the first time is ambiguous but the second time is definite,
           the time interval may be ambiguous 
*/

        
else if((first_ambi == 0 && start_time <= 12&& (second_ambi == 1 || end_time > 12)) 
        
{
            
if(start_time + 12 < end_time)
            
{
                
if(message_number < 1)
                    message_number 
= AMBIGUOUS;
            }

            
if(end_time < start_time && message_number < 2
                message_number 
= END_BEFORE_START;
        }

        
/* When the two times are both ambiguous, we have to check if there is only one pair of times 
        that can be calculated 
*/

        
else if((first_ambi == 0 && start_time <= 12&& (second_ambi == 0 &&  (end_time <= 12 || end_time == 24)))
        
{
              
if(start_time == 0 && (end_time == 0 || end_time == 24&& message_number < 1)
                  message_number 
= AMBIGUOUS;
              
if(start_time >= end_time)
                  end_time 
= end_time + 12;  /* if end_time + 12, then end_time must be greater than start_time */
            
else if((start_time < end_time) && message_number < 1
                message_number 
= AMBIGUOUS;
        }


        
/* if the input time ends with 'm', read one more character */
        
if(c == 'm')
            c 
= getchar();
        
while(c != '\n')
        
{
            
/* when the input contains something else except the white space after the second time,
               print error message
*/

            
if(c != '\t' && c != ' ' && c != '\0'
                message_number 
= INVALID_SYNTAX;
            c 
= getchar();
        }


        
/* One message should be print. That depends on the specified priority */ 
        
if(message_number == 5)
            printf(
"invalid syntax\n");
        
else if(message_number == 4
            printf(
"overflow\n");
        
else if(message_number == 3)
            printf(
"impossible time\n");
        
else if(message_number == 2)
            printf(
"end before start\n"); 
        
else if(message_number == 1)
            printf(
"ambiguous\n");
        
else
            printf(
"%d\n", end_time - start_time);  /* printf the number of hours worked */

    }

    
return 0;
}

博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3