2013-11-21 97 views
0

在成功運行entabulator之後,我的detabulator將不會選擇應該退出while循環的字符比較。將「0(製表符)8(進入)(ctrl + D)」作爲輸入後,製表符被正確寫入空格,但rp遞增後指向8,應讀取8的while循環不會退出我得到一個seg故障。這裏的代碼:C:字符比較失敗

#include <string.h> 
#include <stdio.h> 
#define MAXLINE 100 
char doc[9001]; 
main(int argc, char *argv[]) 
{ 
    int max = 0; 
    char *rp = doc; 
    char *wp = rp; 
    char *tf = wp; 
    char *lp = doc; 

    while ((*(rp++) = getchar()) != EOF); 
    *--rp = '\0'; 
    rp = doc; 
    j = 0; 
    while ((*rp != '\0') && (argc == 1)) { 
     if (*rp == '\n') { 
      lp = rp + 1; 
      *wp++ = *rp++; 
     } 

     while((*rp != '\t') && (*rp != '\0') && (*rp != '\n')) { /*this loops after a tab*/ 
      *wp++ = *rp++; 
     } 
     if (*rp == '\t') { 
      rp++; 
      tf = lp + ((((wp - lp)/8) + 1) * 8); 
      while ((tf - wp) != 0) 
       *wp++ = 's'; 
     } 
    } 
    if (*rp == '\0')  
     *wp = '\0'; 
    printf("%s\n", doc); 
} 

回答

0

我覺得是,下面的循環會進入無限循環。

while((*rp != '\t') && (*rp != '\0') && (*rp != '\n')) { /*this loops after a tab*/ 
    *wp++ = *rp++; 

這是因爲,你檢查rp!= '\t'等,但這裏

if (*rp == '\t') 
{ 
    rp++; 
    tf = lp + ((((wp - lp)/8) + 1) * 8); 
    while ((tf - wp) != 0) 
     *wp++ = 's'; 
} 

你用炭's'填充doc陣列和這比寫'\t'也,所以上面的循環將會無限。

+0

你說得對,我看不懂的輸入,因爲我已經覆蓋它。謝謝。 – user3003268

1

初始輸入循環還有一些尚未解決的問題。

即使您爲其分配了9001個字節,也不應冒着溢出緩衝區的風險。這就是病毒和事件如何闖入程序。此外,你有一個問題,因爲你正在比較一個字符與EOF。不幸的是,getchar()返回一個int:它不得不因爲它返回任何有效的字符值作爲正值,而EOF作爲負值返回(通常爲-1,但沒有什麼能保證該值)。

所以,你可以寫這個循環更安全,並明確,如:

char *end = doc + sizeof(doc) - 1; 
int c; 

while (rp < end && (c = getchar()) != EOF) 
    *rp++ = c; 
*rp = '\0'; 

隨着你的循環書面的兩種不良情況之一發生:

  • 如果char是一個無符號鍵入,那麼你將永遠不會檢測到EOF。
  • 如果char是一個有符號的類型,那麼當你讀到一個有效的字符時(通常是ÿ,y-變音符號,帶有DIAERESIS的拉丁小字母Y,U + 00FF),你將檢測到EOF。

兩者都不好。上面的代碼避免了這兩個問題,無需知道普通的char是有符號還是無符號的。

傳統上,如果你有一個空的循環體,你可以通過將分號放在一行上來強調它。在while條件之後,許多無限循環都是由分數分號引起的;通過在下一行放置分號,你強調它是有意的,而不是偶然的。

while ((*(rp++) = getchar()) != EOF); 

while ((*(rp++) = getchar()) != EOF) 
    ; 
+0

您分析問題的方式非常棒! – 2013-11-21 05:29:52

+0

感謝您向我展示代碼失敗的地方。顯然我需要記住可移植性和安全性問題。 – user3003268