2014-07-03 260 views
1

所以我現在想通過K & R,我很困惑這裏發生了什麼。在我添加空格的for循環行中,模數運算正確計算。它運行正確的時間。但是將相同的模數運算分配給spaces_to_add會返回錯誤的結果。 (通常存儲i_new_str本身。)C - 模數返回錯誤結果?

有關爲什麼會發生這種情況的任何想法?

// replaces tabs with spaces up until next tab stop 
void detab(char str[]) { 
     char new_str[STR_LEN], c; 
     int i, j, i_new_str, spaces_to_add; 
     i_new_str = 0; 
     while((c = str[i++])) { 
       if(c == '\t') { 
         spaces_to_add = i_new_str % SPACES_FOR_TAB; 
         printf("%d\n", spaces_to_add); 
         for(j = 0; j < (i_new_str % SPACES_FOR_TAB); ++j) { 
           printf("Adding space\n"); 
           new_str[i_new_str++] = ' '; 
         }   
       } else {  
         new_str[i_new_str++] = c; 
       }   
     }   

     for(i = 0; new_str[i]; ++i) { 
       str[i] = new_str[i]; 
     }   
     str[i] = '\0'; 

     printf("str changed to length %d\n", i); 
} 

這裏的一些輸出與一些代碼示例,這不是上面貼:

a b c 
Input was: 
a b c 
Length of input: 5 

spaces_to_add = 1 (1 % 8) 
Adding space 
Adding space 
Adding space 
Adding space 
Adding space 
Adding space 
Adding space 
spaces_to_add = 1 (9 % 8) 
Adding space 
Adding space 
Adding space 
Adding space 
Adding space 
Adding space 
Adding space 
str changed to length 17 
Detabbed str: 
a  b  c 
+0

請注意,您在'j'上的循環將爲'SPACES_FOR_TAB - spaces_to_add'運行。把'i_new_str%SPACES_FOR_TAB'想象成有多少個字符位置**通過最後一個tabstop **,而你的for循環在'j'上會計算下一個字符串**有多少個字符位置**。 – rslemos

+0

其實不要。等一下。只要放下'j'。將其更改爲'while(i_new_str%SPACES_FOR_TAB){... i_new_str ++ ...}'。或者......至少在一個空間中做{...} while(...)'。 – rslemos

+0

@rslemos哇。我甚至沒有意識到我在增加i_new_str,這就是我被拋棄的原因。儘管如此,我並沒有正確地考慮邏輯,所以謝謝你解釋!而這絕對看起來更好的編程風格,非常感謝你! – Bitani

回答

1

表達(i_new_str % SPACES_FOR_TAB)在循環在每次迭代獲取評估,而分配循環之前只計算一次。

0

從問題的說明(完整的空間,直到下一個製表位),請注意您應該計算多少空間下一個製表位(沒有多少過最後一個製表位)。

也就是說

SPACES_FOR_TAB - i_new_str % SPACES_FOR_TAB 

(而不是你的i_new_str % SPACES_FOR_TAB)。

也就是說,看看你的for循環(通過j):它計數j直到i_new_str % SPACES_FOR_TAB,完全改變i_new_str。

要麼你計數前計算你的極限,或者根本不指望:

while (i_new_str % SPACES_FOR_TAB) { 
    printf("Adding space\n"); 
    new_str[i_new_str++] = ' '; 
} 

注意上面的解決方案將錯過情況下選項卡正在處理正是在製表位的第一環。要添加一個必需空間:

do { 
    printf("Adding space\n"); 
    new_str[i_new_str++] = ' '; 
} while (i_new_str % SPACES_FOR_TAB);