2013-05-20 2 views
0

У меня есть очень простой кусок кода, который проверяет, является ли число дано перестановкаПочему цикл в C проходит только один раз?

(количество цифр < 8, каждая из цифр показывает только один раз)

от неизвестных причин мне цикл с отмеченными комментарий (HERE) проходит только один раз. Может ли кто-нибудь помочь мне в этом?

#include <stdio.h> 
#include <stdbool.h> 

int num_digits(int number) 
{ 
    int digits = 0; 
    while (number) { 
     number /= 10; 
     digits++; 
    } 
    return digits; 
} 

int get_n_digit(int number, int which) 
{ 
    if(which > num_digits(number)) 
    { 
    printf("This number %d does not have that many digits: %d\n",number, which); 
    return -1; 
    } 

    int to_return = number; 
    int i = 0; 
    for(i = 0; i < num_digits(number) - which;i++) 
    { 
    int digit = number % 10; 
    to_return /= 10; 
    } 
    printf("get_n_digit(%d,%d)=%d\n",number,which, to_return %10); 
    return to_return % 10; 
} 

bool permutation_check(int number) 
{ 
    bool to_return = true; 
    if(num_digits(number) > 8) 
    { 
    printf("Your number has more than 8 digits\n"); 
    return false; 
    } 
    int temp[10]; 
    int i; 
    for(i = 0; i < 10; i++) 
    { 
    temp[i]=0; 
    } 

    printf(" for(i = 0; i < num_digits(%d) = %d; i++)\n",number, num_digits(number)); 
    for(i = 0; i < num_digits(number); i++); 
    { 
    //HERE 
    printf("temp[get_n_digit(%d,%d)]++;\n",number,i); 
    temp[get_n_digit(number,i)]++; 
    if(temp[get_n_digit(number,i)] > 1) 
    { 
     to_return = false; 
    } 
    } 

    for(i = 0; i < 10; i++) 
    { 
    printf("%d\n",temp[i]); 
    } 
    return to_return; 
} 

int main(void) 
{ 
    char line[256]; 
    int i, a; 
    printf("Put a number to be checked for permutation condition.\n"); 
    if (fgets(line, sizeof(line), stdin)) { 
     if (1 == sscanf(line, "%d", &i)) { 
     printf("This many digits in this number: %d\n", num_digits(i)); 
     if(num_digits(i)<8) 
     { 
      if(permutation_check(i)) 
      printf("This number is a permutation.\n"); 
      else 
      printf("This number is NOT a permutation.\n"); 
     } 
    } 
    } 
    return 0; 
} 
+1

У вашего 'num_digits' есть ошибка - он возвращает ноль, когда' number' передается в ноль, в то время как нуль принимает одну цифру для представления. – dasblinkenlight

ответ

16

У вас есть точка с запятой в конце вашего заявления для

for(i = 0; i < num_digits(number); i++); // <-- Semicolon 
+1

Поднятый отвратительным форматированием. Совсем немного менее вероятно, если вы поместите '{' в ту же строку, что и оператор 'for'. –

+0

ОН ... МОЙ ... БОГ ... Может быть, мне нужно наконец убедить себя в фигурных скобках в конце линии. Большое спасибо. – Patryk

+3

Один из малоизвестных бонусов C++: поскольку у вас обычно есть переменная цикла локально, этот код должен давать ошибку 'for (int i = 0; i <10; ++ i); arr [i] = 42; ' – Roddy

4

Во-первых пожалуйста компилировать с -Wall -Werror -Wextra. В частности, этот сигнал улавливается -Wempty-body, который активируется -Wextra, но не -Wall. Вы не смогли бы совершить эту ошибку вообще.

Лучший способ узнать, что не так с вашим кодом, - это точно понять, что он делает. Для этого нужны отладчики. Вы можете сделать это в своей среде IDE, и если вы не используете IDE, то инструмент для использования на * nix - gdb.

  1. Скомпилируйте ваш код с помощью флага -g.
  2. Запуск как, например, gdb a.out.
  3. Установить точку останова в основной - (GDB) сломаться главный
  4. Run - (gdb) run

Шаг через код и увидеть именно то, что он делает, и где оно нарушает ваши ожидания. В Eclipse дважды щелкните номер строки рядом с главной функцией, чтобы установить точку останова, и запустите, нажав на значок отладки, который, вероятно, является графикой насекомого. Visual Studio C++, я думаю, будет аналогичным.

В вашем случае вы хотите установить точку останова на линии, в которой работает цикл for.

gdb break <line #> 

Then next ваш путь через. Для простого файла кода, подобного этому, скорее всего, будет сразу видно, что происходит - или, по крайней мере, у вас будет гораздо более конкретная проблема для работы.

Приблизительность этого ответа покрыта on meta.

+1

Я не уверен, что одношаговый ответит на это. Он сказал бы ему точно, что он уже знал, что тело цикла было исполнено только один раз. Это не объясняет * почему *. – Barmar

+0

@ Бармар, возможно, я готов поспорить, что он получил бы это, посмотрев на эту линию на 10 циклов :) Примечание. Я начал этот ответ, прежде чем # 1 отправил ';'.но я также заметил, что предупреждения компилятора поймали бы это; добавлен в ответ. – djechlin

+0

Спасибо за ответ, хотя '-Wall -Werror' не улавливает цикл'; 'сразу после цикла. – Patryk