修复我的简单数字程序中的错误(C)

时间:2016-04-13 20:54:14

标签: c debugging

Welp,我的任务是编写一个程序,如果在命令行中使用数字执行,则计算不同的数字并输出重复的数字,如下所示:

./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

编辑:

顶部缺少的部分是:

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

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

3 个答案:

答案 0 :(得分: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. 由于您使用的是intatoi,因此您必须记住仅将输入限制为正整数。

  3. 只需增加数组元素value % 10即可完成数字计数。

  4. 虽然您似乎正确使用while,但打印时使用的正确循环类型为for。这就是它的用途。

  5. 您将收到编译器发出的警告:您未使用argc。为了安全起见,最好在顶部添加一个测试,以便检查您的输入。

  6. 类似于int main没有返回任何内容。

答案 1 :(得分:0)

修复

您正在递增错误的索引。

digit_amount[j]++;

应该是

digit_amount[digit]++;

您可以在https://ideone.com/ajbJnd

看到代码

注意:工作代码int input = atoi(argv[1]);中的内容已替换为int input = atoi("31344842");。如果你改回来它应该在程序中工作!

不同的方式

更简洁的方法是将输入用作字符串,而不是将其转换为int。

代码示例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;
}

答案 2 :(得分: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”后跟2,000个零可以作为字符串处理,但不能在PC硬件上表示为整数。

同样,像{100}这样的参数可能由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]);