2013-11-21 3 views
0

После успешного запуска entabulator мой дебатулятор не будет воспринимать сравнение символов, которое должно выйти из цикла while. После попытки «0 (вкладка) 8 (введите) (ctrl + D)» в качестве вклада вкладка правильно написана как пробелы, но после того, как rp будет увеличен до 8, цикл while, который должен прочитать 8, не выйдет и я получаю ошибку 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'; 
} 

вы заполняете doc массив с полукокса 's' и что над письменной '\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 является подписанным типом, то вы обнаружите EOF, когда будете читать действительный символ (часто ÿ, y-умлаут, LATIN SMALL LETTER Y WITH DIAERESIS, U + 00FF).

Ничто не является хорошим. В приведенном выше коде избегаются обе проблемы, не требуя знать, подписана ли или нет подпись char.

Обычно, если у вас есть пустое тело цикла, вы подчеркиваете это, поместив точку с запятой в линию самостоятельно. Многие бесконечные петли были вызваны бездомной точкой с запятой после условия while; поставив точку с запятой на следующую строку, вы подчеркиваете, что она преднамеренная, а не случайная.

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

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

То, как вы анализируете проблему, УДИВИТЕЛЬНО !!! –

+0

Благодарим вас за то, что вы показали мне эти места, где код не удался. Ясно, что я должен помнить о переносимости и проблемах безопасности. – user3003268

Смежные вопросы