2016-04-13 6 views
-1

Welp, мне поручено написать программу, которая, если выполняется с номером в командной строке, подсчитывает разные цифры и выдает повторяющиеся, например:Исправление ошибки в моей простой цифровой программе (C)

./digitcount 31344842 
"3" occurs 2 times. 
"4" occurs 3 times. 

Однако, я просто не могу заставить его работать:

int n = input; 
int digit_count = 0; 
while(n!=0)      //count amount of digits in input 
{ 
    digit_count++; 
    n /= 10; 
} 
int digit_array[digit_count]; //create array for digits 

int i = digit_count; 
while(i!=0)      //assign digits to array elements 
{ 
    digit_array[i-1] = input % 10; 
    input /= 10; 
    i--; 
} 

//count number of times a digit has appeared 
int digit_amount[10] = {0,0,0,0,0,0,0,0,0,0}; 
int digit = 0; 
while(digit<10) 
{ 
    int j = 0; 
    while(j <= digit_count) 
    { 
     if(digit_array[j] == digit) 
     { 
      digit_amount[j]++; 
     } 
     j++; 
    } 
    digit++; 
} 
//final output 
printf("Repeated digits:\n"); 
int k = 0; 
while(k<10) 
{ 
    if(digit_amount[k] >= 2) 
    { 
     printf("\"%i\" occurs %i times.\n",k,digit_amount[k]); 
    } 
    k++; 
} 

Когда я скомпилировать программу, никаких ошибок/предупреждений не отображаются, но при исполнении я только получаю:

Repeated digits: 

Я пробовал довольно много с ним и понял, что все работает до тех пор, пока программа не начнет подсчитывать количество цифр, тогда каждое число считается включенным один раз и только один раз.

Кто-нибудь знает, что произошло здесь? PS: Я довольно скраб при программировании, поэтому, пожалуйста, любезно мне, если я сделал некоторые действительно тупой ошибки: P

EDIT:

Часть отсутствует на самом верху:

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char * argv[]) 
{ 
    int input = atoi(argv[1]); 
+2

Как и то, что 'input' установлен? Пожалуйста, покажите [минимальный полный и проверяемый пример] (http://stackoverflow.com/help/mcve) – kaylum

+0

int digit_array [digit_count]; не работает .. читать на динамически распределенных массивах (malloc) – gidim

+0

Пожалуйста, включите ваш метод 'main()'. Например, вы правильно конвертируете 'argv [1]' (т. Е. Число) из 'char *' в 'int'? – tobiasvl

ответ

0

Вы излишне усложнили эту задачу, введя второй массив. Я пытался следовать своему мышлению, но отказался и написал вместо этого:

#include <stdio.h> 
#include <stdlib.h> 

int main (int argc, char *argv[]) 
{ 
    if (argc != 2) 
    { 
     printf ("no input?\n"); 
     return -1; 
    } 
    int digit_amount[10] = {0}; 
    int input = atoi(argv[1]); 

    while (input) 
    { 
     digit_amount[input % 10]++; 
     input /= 10; 
    } 

    printf("Repeated digits:\n"); 
    int k; 
    for (k=0; k<10; k++) 
    { 
     if(digit_amount[k] >= 2) 
     { 
      printf("\"%i\" occurs %i times.\n",k,digit_amount[k]); 
     } 
    } 

    return 0; 
} 

Нескольких случайных заметок:

  1. Вам не нужно явно задавать каждый член digit_amount 0. Просто первое достаточно, чтобы указать компилятору, что весь массив должен быть инициализирован до нуля.

  2. Поскольку вы используете int и atoi, вы должны помнить, что ограничиваете свой ввод только положительными целыми числами.

  3. Подсчет цифр можно просто увеличить с помощью элемента массива value % 10.

  4. Правильно ли вы используете while, правильный тип петли для печати при печати составляет for. Вот для чего это.

  5. Вы получите предупреждение от своего компилятора, что вы не использовали argc. Для обеспечения безопасности лучше всего добавить тест вверху, чтобы ваш вход был проверен.

  6. Как и в случае с int main ничего не возвращающего.

0

Исправление

Вы приращение неправильного индекса.

digit_amount[j]++; 

должен быть

digit_amount[digit]++; 

Вы можете увидеть код работает на https://ideone.com/ajbJnd

ПРИМЕЧАНИЕ: что в рабочем коде int input = atoi(argv[1]); был заменен int input = atoi("31344842");. Если вы измените его, он будет работать так же, как и в вашей программе!

Иной путь

уборщик способ сделать это было бы использовать вход в виде строки вместо преобразования его в междунар.

Пример кода https://ideone.com/F0PTFz

Код Источник:

#include <stdio.h> 
#include <string.h> 

int main(int argc, char * argv[]) { 
    char* input = "31344842"; 
    int digit_count = 0; 

    digit_count = strlen(input); //count amount of digits in input 


    //count number of times a digit has appeared 
    int digit_amount[10] = {0,0,0,0,0,0,0,0,0,0}; 
    int digit = 0; 
    while(digit<10) 
    { 
     int count = 0; 
     char* singleDigit[1]; 
     while(count <= digit_count) 
     { 
      // Subtracting the character 0 from a character will give you its real int value 
      if((input[count] - '0') == digit) 
      { 
       digit_amount[digit]++; 
      } 
      count++; 
     } 
     digit++; 
    } 
    //final output 
    printf("Repeated digits:\n"); 
    int k = 0; 
    while(k<10) 
    { 
     if(digit_amount[k] >= 2) 
     { 
      printf("\"%i\" occurs %i times.\n",k,digit_amount[k]); 
     } 
     k++; 
    } 
    return 0; 
} 
+0

Если мой ответ помог исправить вашу проблему, вы могли бы отметить ее как принятый ответ –

0

Я предполагаю, что вы только учитесь C. Я не знаю, если вы знакомы со строками и символами еще, или нет. Итак, давайте посмотрим на два способа получить цифры.

Строка подход

Во-первых, вы можете воспользоваться тем, что вы знаете, вы получаете строки аргумент командной строки, которая должна состоять из ряда ASCII цифровых символов. Цифры ASCII представлены целыми значениями 48..57 (основание 10) или 0x30..0x39 (основание 16). Цифры запускаются последовательно из 0, 1, ... 9, поэтому вы можете легко выполнять сравнения строк, и вы можете делать простые математические вычисления. В частности, d - '0' преобразует цифру d в числовое значение этой цифры.

const char * Usage = "Usage: myprog INT\n"; 

void 
usage(void) 
{ 
    print(Usage); 
    exit(1); 
} 

int 
main(int argc, const char *argv[]) 
{ 
    if (argc < 2) 
     usage(); 

    const char * digitp = argv[1]; 
    int digit_val; 

    while (*digitp) { 
     if (!isdigit(*digitp)) 
      usage(); 

     digit_val = *digitp++ - '0'; 
     /* At this point digit_val contains a numeric value from 0..9 */ 
    } 

    exit(0); 
} 

Целочисленное подход

Строка подход является правильный путь, если вы не знаете, о символах и строках или каким-то образом должны делать это по-другому с помощью своего класса. В этом случае, мы возьмем некоторые из существующего кода:

int 
main(int argc, const char *argv[]) 
{ 
    if (argc < 2) 
     usage(); 

    int number = atoi(argv[1]); 

    do { 
     digit_val = number % 10; 
     number /= 10; 

     /* At this point digit_val contains a numeric value from 0..9 */ 

    } 
    while (number != 0); 

    exit(0); 
} 

Обратите внимание, что эти два скелеты другого. Возможно, вам будет все равно, но обработка значения в виде строки позволяет обрабатывать длинные последовательности цифр, которые могут вызвать переполнение при вызове atoi. Например, «1», за которым следует 2000 нулей, можно обрабатывать как строку, но не может быть представлено как целое число на аппаратном обеспечении ПК.

Аналогично, параметр «100x» может быть проанализирован atoi, но будет помечен как ошибка строковым подходом.

Работа с цифрами

После того, как у вас есть цикл с каждой цифрой в нем, что вы делаете? Ваш код был на правильном пути:

digit_amount[digit_val] += 1; /* increase frequency count */ 

Это ВСЕ! Вы считаете, как часто появляются цифры, вам больше не нужно делать.

После цикла закончена, вы можете обрабатывать все 10 отсчетов частоты и увидеть, если любой из них повторялись:

for (int digit = 0; digit < 10; ++digit) 
    if (digit_amount[digit] > 1) 
     printf("Digit %d is repeated %d times\n", digit, digit_amount[digit]); 
Смежные вопросы