2017-10-05 129 views
0

寫該方法用以下標準意想不到輸出..掌握錯誤

INPUT:aa​​bbb OUTPUT:A2B3

INPUT:AB輸出:AB(因爲它比A1B1短)

INPUT: a23輸出:錯誤(不讀取數字)

這是我目前使用的方法。

void encrypt(char* crypt, const char* source) { 


    while (1) { 

     char tmp = *source; 

     if (!tmp) { 
      *crypt = 0; 
      printf("error\n"); 
      return; 
     } 

     size_t count = 1; 
     while (*(++source) == tmp){ 
      if(isdigit(tmp)){ 
       printf("error\n"); 
       return; 
      } 
      ++count; 
     } 
     *(crypt++) = tmp; 
     crypt += sprintf(crypt, "%zu", count); 
    } 

} 

int main(int argc, char **argv) { 

    if (argc != 2) { 
     fprintf(stderr, "error\n"); 
     return 1; 
    } 

    const char* source = argv[1]; 

    char* crypt = malloc(strlen(source)*2+1); 

    encrypt(crypt, source); 
    printf("%s\n", crypt); 
// free(crypt); 
    return 0; 

} 

非常奇怪的是,每次我跑這個時候,我得到的輸出:

./prog abbbb 
error 
a1b4 

./prog a23r 
error 
a1 

爲什麼這個錯誤出現?我怎樣才能讓第一個錯誤信息停止出現,以及爲什麼當輸入字符串中間有數字時程序不會中斷?

+0

該程序非常適合調試器。 –

+0

老實說,非常令人尷尬的是不知道如何正確使用調試器,並且通過ssh和vim使用遠程機器 – sgerbhctim

+0

您需要一個當字符串結束時正常結束的路徑。 – BLUEPIXY

回答

-1

第一種情況:abbbb

調用該函數encrypt(),其中準備串a1b4在你分配(sprintf()發生在內存中,不會引起任何被顯示在控制檯上)的緩衝。

該字符串以空終止符終止。當你的循環到達這一點時,tmp將爲空。不幸的是,這會導致在控制檯上打印一條即時消息error。然後函數返回,並打印緩衝區中的結果。

第二種情況:a23r

首先,encrypt()開始解析輸入字符串,並創建了有效的字母輸出字符串。這產生a1。在第二次迭代時,它遇到數字'2',這導致isdigit(tmp)爲真。再次,控制檯立即輸出error。該函數然後返回。但a1已經在緩衝區中,所以它也輸出到控制檯。

如何以正確的順序獲取物品?

更改您的功能,以便通知調用者錯誤情況。例如,返回0意味着好,另一個值意味着發生錯誤。

#define ERR_EMPTY 1   /* error: empty string */ 
#define ERR_INVALID 2   /* error: invalid character */ 

int encrypt(char* crypt, const char* source) { 
    int rc = 0;     // return= 0; 

    if (!*source)     // if input string is empty 
     rc = ERR_EMPTY; 
    else {  
     while (*source) {    // loop while the char is not zero 
      char tmp = *source; 
             // (don't show a error at the null terminator) 
      if(isdigit(tmp)){ 
       rc = ERR_INVALID; 
       break; 
      } 
      size_t count = 1; 
      while (*(++source) == tmp){ 
       ++count; 
      } 
      *(crypt++) = tmp; 
      crypt += sprintf(crypt, "%zu", count); 
     } 
    } 
    *crypt = 0; // prevent risks: in every case put a null terminator 
    return (rc); 
} 

隨着這一變化,然後你可以更好地控制main()輸出:

int err = encrypt(crypt, source); 
if (!err) 
    printf("%s\n", crypt); 
else printf ("Error (code %d)\n", err); 

最後再說一句

注意:malloc(strlen(source)*2+1)假定strlen(source)<(SIZE_MAX-1)/2。如果不滿足此條件,則可能會遇到整數溢出,導致分配不足和內存損壞。