為何生肖可以執行而星座不能

Home Home
引用 | 編輯 csr
2011-07-07 22:31
樓主
推文 x0
#include<stdio.h>
#include<stdlib.h>

int main(void)
{
int y;

printf("請輸入出生年:");
scanf("%d",&y);

if(y%12==1){
printf("生肖:鼠\n");
}
else if(y%12==2){
printf("生肖:牛\n");
}
else if(y%12==3){
printf("生肖:虎\n");
}
else if(y%12==4){
printf("生肖:兔\n");
}
else if(y%12==5){
printf("生肖:龍\n");
}
else if(y%12==6){
printf("生肖:蛇\n");
}
else if(y%12==7){
printf("生肖:馬\n");
}
else if(y%12==8){
printf("生肖:羊\n");
}
else if(y%12==9){
printf("生肖:猴\n");
}
else if(y%12==10){
printf("生肖:雞\n");
}
else if(y%12==11){
printf("生肖:狗\n" ..

訪客只能看到部份內容,免費 加入會員



獻花 x0
引用 | 編輯 ebolaman
2011-07-08 00:56
1樓
  
>> 星座表 <<


我真是佩服你一個一個慢慢打,然而

我並沒有發現有什麼奇怪的錯誤,不能執行之類的

你所提供的程式碼 運行一切 OK。


不能執行的解釋是? 輸入的 "月" 和 "日" 與 結果不符嗎? 那就是你輸入的格式打錯了,正確的例如:

12 21

還是其他? 請詳細說明



另外我忽然也想要練習一下 C++,這是仿造你的程式碼打出來的

主要功能一模一樣,但是更簡化,可以參考



複製程式
#include<stdio.h>
#include<stdlib.h>

/*----- Prototype -----*/
char* get_str(char*, int, int);
int check_range(int*, int);
/*_____________________*/ 

/*----- Variables -----*/
char* tempc;
/*_____________________*/



int main()
{ 
  /*----- Variables -----*/
  char* str_year;  //Year
  char* str_cnstl; //Constellation
  
  int input[3];
  
  int i;
  /*_____________________*/
  
  
  /*--- Set up strings for displaying ---*/
  //str_year=(char*)malloc((2+1)*(12)*sizeof(char));
  //str_cnstl=(char*)malloc((4+1)*(12)*sizeof(char));
  
  str_year="鼠,牛,虎,兔,龍,蛇,馬,羊,猴,雞,狗,豬";
  str_cnstl="水瓶,雙魚,牧羊,金牛,雙子,巨蟹,獅子,處女,天秤,天蠍,射手,摩羯";
  /*_____________________________________*/
  
  
  /*--- Retrieve data from user ---*/
  printf("請輸入出生的 年/月/日 :\n");
  printf("例 : 2012/12/21\n>");
  scanf("%d/%d/%d",&input[0],&input[1],&input[2]);
  /*_______________________________*/
  
  
  /*--- Determine the range ---*/
  
  //Year
  printf("生肖: %s\n", get_str(str_year, 2, ((input[0]-1911)%12-1) ));
  free(tempc);
  
  //Constellation
  for (i=0; i<12; ++i)
    if (check_range(input, i)==1)
    {
      printf("星座: %s座\n", get_str(str_cnstl, 4, i ));
      free(tempc);
      break;
    }
  
  if (i==12)
    printf("日期好像打錯了,無法判斷星座\n");
  
  printf("\n");
  
  /*___________________________*/
  
  
  
  /*--- Free memories ---*/
  //free(str_year);
  //free(str_cnstl);
  /*_____________________*/
  
  
  system("pause");
  return 0;
} 


char* get_str(char* str, int symb_len, int ind)
{
  int i=0;
  
  tempc=(char*)malloc((symb_len+1)*sizeof(char));
  
    for (i=0; i<symb_len; ++i)
      tempc[i]=str[ind*(symb_len+1)+i];
    
    tempc[i]='\0';
  
  return tempc;
}


int check_range(int* input, int ind)
{
    
    int range [2][12][2]={{1,20, 2,19, 3,21, 4,20, 5,21, 6,22, 7,23, 8,23,  9,23, 10,24, 11,23, 12,22},
                          {2,18, 3,20, 4,19, 5,20, 6,21, 7,22, 8,22, 9,22, 10,23, 11,22, 12,21,  1,19}};
    int daymax;
    int arr_daymax[12][2]={1,31, 2,28, 3,31, 4,30, 5,31, 6,30, 7,31, 8,31,  9,30, 10,31, 11,30, 12,31};
    
    //Read daymax
    daymax=arr_daymax[input[1]-1][1];
    
    //Exception
    if (input[1]==2)
      if((input[0]%4)==0 && (input[0]%100)!=0 || (input[0]%400) ==0)
        daymax=29;
    
    //Main part
    if (input[1]>=range[0][ind][0] && input[1]<=range[1][ind][0] )
      if (input[1]==range[0][ind][0] && input[2]>=range[0][ind][1] || input[1]==range[1][ind][0] && input[2]<=range[1][ind][1])
        if (input[2]>=1 && input[2]<=daymax)
          return 1;

}



獻花 x4
引用 | 編輯 三仙
2011-07-08 07:56
2樓
  
樓主 表情 你忘了交待一下你的寫作環境了

獻花 x1
引用 | 編輯 csr
2011-07-08 21:30
3樓
  
下面是引用 三仙 於 2011-07-08 07:56 發表的 : 到引言文
樓主 表情 你忘了交待一下你的寫作環境了


以上是小弟用dev c++ compiler
而debug也都ok
但是星座就是不出來
是否小弟那裡打錯
請大大指正
謝謝

版大
謝謝
小弟找到錯誤的地方了
else if(m==6&&d>=22&&d<=30||m==7&&d>=1&&d<=22)
  {
    printf("星座:巨蟹座\n");
紅色部份打錯了
所以從一月到六月都可以就是七月出問題
然後八月以後也可以
所以仔細看了以後
才發現> 及<打錯了
謝謝版大

獻花 x0
引用 | 編輯 csr
2011-07-08 21:44
4樓
  
下面是引用 ebolaman 於 2011-07-08 00:56 發表的 : 到引言文
>> 星座表 <<

我真是佩服你一個一個慢慢打,然而
我並沒有發現有什麼奇怪的錯誤,不能執行之類的
你所提供的程式碼 運行一切 OK。
.......
大大你好
小弟看了你寫的程式
真是佩服
小弟能力還沒到這樣的功力
只能把大大的程式下載來研究
希望有朝一日也可與大大比較
謝謝

獻花 x0
引用 | 編輯 csr
2011-07-08 22:14
5樓
  
下面是引用 於 1970-01-01 07:00 發表的 : 到引言文
大大
很湊巧
可能在同一時間
大大跟小弟都會心一笑
真的是世上無奇有
小弟的無心錯誤特別多
真的謝謝你
不過真的小弟對於大大的程式還真似懂非懂
要好好研究一下資料結構系列
希望能在大大後面慢慢追
謝謝

獻花 x0
引用 | 編輯 ebolaman
2011-07-08 23:22
6樓
  
下面是引用 csr 於 2011-07-08 22:14 發表的 : 到引言文

大大
很湊巧
可能在同一時間
大大跟小弟都會心一笑
真的是世上無奇有
小弟的無心錯誤特別多
真的謝謝你
不過真的小弟對於大大的程式還真似懂非懂
要好好研究一下資料結構系列
希望能在大大後面慢慢追
謝謝

湊巧也過了頭,還真的是蠻神奇的

老實說,暑假前我根本不知道 C++ 的資料結構
我只是 細心玩味地 讀完了 "一本" C語言的書而已
大家都是要互相學習的,沒有你這個提問,我也不會開始重視 "日期" 格式的偵測

地球在轉,我們一起前進。

獻花 x0
引用 | 編輯 csr
2011-07-09 14:58
7樓
  
下面是引用 ebolaman 於 2011-07-08 23:22 發表的 : 到引言文


湊巧也過了頭,還真的是蠻神奇的

老實說,暑假前我根本不知道 C++ 的資料結構
我只是 細心玩味地 讀完了 "一本" C語言的書而已
大家都是要互相學習的,沒有你這個提問,我也不會開始重視 "日期" 格式的偵測

地球在轉,我們一起前進。
大大
感恩您的勉勵
下次有機會
恐怕還要向您指教
謝謝

獻花 x0
引用 | 編輯 星辰雪
2011-07-09 21:57
8樓
  
下面是引用 ebolaman 於 2011-07-08 00:56 發表的 : 到引言文
>> 星座表 <<

我真是佩服你一個一個慢慢打,然而
我並沒有發現有什麼奇怪的錯誤,不能執行之類的
你所提供的程式碼 運行一切 OK。
.......

請問一下 我有一些疑問
str_year=(char*)malloc((2+1)*(12)*2*sizeof(char));
str_cnstl=(char*)malloc((4+1)*(12)*2*sizeof(char));

-----------以上這兩行我不太懂 這兩行的意思
可以解釋一下嗎

獻花 x0
引用 | 編輯 ebolaman
2011-07-10 09:50
9樓
  
下面是引用 星辰雪 於 2011-07-09 21:57 發表的 : 到引言文


請問一下 我有一些疑問
str_year=(char*)malloc((2+1)*(12)*2*sizeof(char));
str_cnstl=(char*)malloc((4+1)*(12)*2*sizeof(char));

-----------以上這兩行我不太懂 這兩行的意思
可以解釋一下嗎


malloc 是動態分配的函數,其實我也不是很懂,當初是在書中看到

主要好像是用在 未知的長度 要分配記憶體使用的

但此處既然 鼠、牛、虎...的長度是確定的,那兩行其實刪除應該會比較好



感覺就像是 malloc 請求 "額外的" 免費記憶體

然後用指標函數指定 對著這個位置,然後我們就能用 ptr[N] 或 *(ptr+N) 等方式去存取

但是你應該注意到了 函數 get_str 那裏面也有用 malloc 現在想起來我沒有用 free 函數把他歸還,會造成 memory leak 不太好





獻花 x1
引用 | 編輯 星辰雪
2011-07-10 20:13
10樓
  
再次請問一下
str_year=(char*)malloc((2+1)*(12)*2*sizeof(char));
str_cnstl=(char*)malloc((4+1)*(12)*2*sizeof(char));

((2+1)*(12)*2*sizeof(char)); 和 ((4+1)*(12)*2*sizeof(char));

2+1是生肖判斷所需要之位數
4+1是星座判斷所需要之位數 對吧
後面的 (12)*2
是什麼意思呢

獻花 x2
引用 | 編輯 三仙
2011-07-10 21:10
11樓
  
下面是引用 星辰雪 於 2011-07-10 20:13 發表的 : 到引言文
再次請問一下
str_year=(char*)malloc((2+1)*(12)*2*sizeof(char));
str_cnstl=(char*)malloc((4+1)*(12)*2*sizeof(char));

((2+1)*(12)*2*sizeof(char)); 和 ((4+1)*(12)*2*sizeof(char));

2+1是生肖判斷所需要之位數
4+1是星座判斷所需要之位數 對吧
後面的 (12)*2
是什麼意思呢
 

記憶體的基本單位
英文字=1 個 Byte
中文字=2 個 Byte


獻花 x2
引用 | 編輯 ebolaman
2011-07-10 21:24
12樓
  
抱歉我又發現我打錯了

應該是要

str_year=(char*)malloc((2+1)*(12)*sizeof(char));
str_cnstl=(char*)malloc((4+1)*(12)*sizeof(char));




至於 str_year=(char*)malloc((2+1)*(12)*sizeof(char));

2 是 例如 "雞" 的長度
1 是我額外好看用的分隔字元 ","

12 是有 十二生肖,至於之前 *2 是我之前只打中文時遺留下來的,打錯了



既然已經

  str_year="鼠,牛,虎,兔,龍,蛇,馬,羊,猴,雞,狗,豬";
  str_cnstl="水瓶,雙魚,牧羊,金牛,雙子,巨蟹,獅子,處女,天秤,天蠍,射手,摩羯";


我現在才終於了解,那些字串已經被載入到記憶體

因此指定符號只是指定 str_year 指標的位置到那個地方,之前 malloc 這個動作是白費力氣了,所以就算刪除也不會有問題

但是 get_str 函數內所需要使用的 tempc 就一定要用 malloc 因為內容需要被更動


唉唉,我對字元與字串還有型態還是搞不太清楚噫

我已經將程式碼重新修改過了,請參考前面回覆部分

獻花 x1
引用 | 編輯 ebolaman
2011-07-10 21:55
13樓
  
下面是引用 三仙 於 2011-07-10 21:10 發表的 : 到引言文
 

記憶體的基本單位
英文字=1 個 Byte
中文字=2 個 Byte


感謝 三仙 大解釋,但我後來發現

不僅 *2 這個是多餘的,連整行 malloc 都是多餘的..



獻花 x0
引用 | 編輯 三仙
2011-07-10 22:02
14樓
  
下面是引用 ebolaman 於 2011-07-10 21:55 發表的 : 到引言文



感謝 三仙 大解釋,但我後來發現

不僅 *2 這個是多餘的,連整行 malloc 都是多餘的..


[attachment=761392]


其實程式就如你說的
已經事先宣告為固定的陣列
後面的動態的部份
其實就把他當做練習好了   表情    不要太在意了

獻花 x0
引用 | 編輯 三仙
2011-07-10 22:05
15樓
  
下面是引用 星辰雪 於 2011-07-10 20:13 發表的 : 到引言文
再次請問一下
str_year=(char*)malloc((2+1)*(12)*2*sizeof(char));
str_cnstl=(char*)malloc((4+1)*(12)*2*sizeof(char));

((2+1)*(12)*2*sizeof(char)); 和 ((4+1)*(12)*2*sizeof(char));

2+1是生肖判斷所需要之位數
4+1是星座判斷所需要之位數 對吧
後面的 (12)*2
是什麼意思呢


呵呵  星辰雪 大的眼睛
果然如鷹眼般的
令在下配服表情

獻花 x0
引用 | 編輯 星辰雪
2011-07-10 22:09
16樓
  
謝謝 兩位的解釋
我現在比較明白了

我也只是碰巧發現而已
看了一下程式發覺那個地方 不懂
才提出來 發問一下

獻花 x0
引用 | 編輯 星辰雪
2011-07-10 22:13
17樓
  
再次發問一下
if (input[1]>=range[0][ind][0] && input[1]<=range[1][ind][0] )

請問一下
[ind] 是什麼意思?
我有看到宣告成 int

獻花 x0
引用 | 編輯 ebolaman
2011-07-10 22:58
18樓
  
下面是引用 星辰雪 於 2011-07-10 22:13 發表的 : 到引言文
再次發問一下
if (input[1]>=range[0][ind][0] && input[1]<=range[1][ind][0] )

請問一下
[ind] 是什麼意思?
我有看到宣告成 int


由於 check_range 是被呼叫的,當初使用他的主部分在這:

for (i=0; i<12; ++i)
   
if (check_range(input, i)==1)
   
{
      printf
("星座: %s座\n", get_str(str_cnstl, 4, i ));
      free
(tempc);
     
break;
   
}


到了 check_range 內部就變成了 ind

為了取得十二星座個別的 日期資料所設計的

例如 ind=0 則是取得 水瓶座 的日期資訊





ind=0 此時

range[0][ind][0] 的資料則是 1 (月份),range[1][ind][0] 則是 2 (月份)



if (input[1]>=range[0][ind][0] && input[1]<=range[1][ind][0] )
檢查 使用者輸入的月份( input[1] ) 是不是在範圍內

if (input[1]==range[0][ind][0] && input[2]>=range[0][ind][1] || input[1]==range[1][ind][0] && input[2]<=range[1][ind][1])
找月份相等的,然後看看日期是不是 高於或低於 (這裡是因為星座範圍剛好上下都是一個月左右,如果突然變成 6 個星座
這樣偵測會出錯,還要加入一些 卡在中間的月份檢查才行)

if (input[2]>=1 && input[2]<=daymax)
檢查日期 (input[2] ) 是不是介於 1 和 daymax(一月份最多的天數) 之間

獻花 x2
引用 | 編輯 csr
2011-07-11 14:21
19樓
  
感謝星辰雪大大
接下來的提問
而且ebolaman大大及版大也能對問題中心作解釋
讓小弟獲益不少
謝謝大家
感恩不盡

獻花 x0