2014-07-03 264 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);