对从 100 到 200 的数字进行排序并告诉我输入的唯一数字数量的代码有问题

Problem with code that orders numbers from 100 to 200 and tells me the amount of unique numbers imput

提问人:Diogo Ruas 提问时间:11/8/2023 最后编辑:Paul T.Diogo Ruas 更新时间:11/10/2023 访问量:72

问:

我正在做一个代码,告诉用户输入 100 到 200 之间的不确定数量的数字。该程序告诉我唯一数字的数量,然后对插补的数字进行排序。这是我的代码:

#include <stdio.h>

void sort(int *numbers, int count) {
   for (int m = 0; m < count; m++) {
        for (int j = 0; j < count - m - 1; j++) {
            if (numbers[j] > numbers[j + 1]) {
               int temp = numbers[j];
                numbers[j] = numbers[j + 1];
                numbers[j + 1] = temp;
            }
        }
    }
}

void printA(int *numbers, int count) {
    for (int i = 0; i < count; i++) {
        printf("%d ", numbers[i]);
    }
    printf("\n");
}

int main() {
    int numbers[101] = {0}; // using an array to keep track of numbers between 100 and 200
    int input, count = 0;

    printf("Enter numbers between 100 and 200 (enter a number outside this range to   finish):\n");

    while (1) {
        scanf("%d", &input);
        if (input < 100 || input > 200) {
            break;
        }
        if (numbers[input - 100] == 0) {
            count++;
            numbers[input - 100] = input;
        }
    }

    printf("\nTotal unique numbers entered: %d\n", count);

    sort(numbers, count);
    printA(numbers, count);

    return 0;
}

该程序告诉我正确输入的唯一数字的数量,但无法对它们进行排序。有人可以告诉我我做错了什么吗?

数组 C 排序 for 循环

评论

1赞 Some programmer dude 11/8/2023
这似乎是学习如何调试程序的好时机。例如,使用调试器逐行单步执行代码,同时监视变量及其值。
0赞 Some programmer dude 11/8/2023
顺便说一句,如果你用来读取输入,你总是需要检查它返回的内容。scanf
2赞 teapot418 11/8/2023
您的数组已经按升序排列,其中混入了大量零。如果你在跳过零的同时打印整个东西,你就不需要这些东西了。numberssort
0赞 teapot418 11/8/2023
如果您想了解发生了什么,请尝试打印出整个表格。然后看看它的第一项。你看到了什么?numberscount
0赞 Harith 11/8/2023
@EricPostpischil我错误地假设了缓冲区溢出漏洞。我已经删除了我的评论。

答:

2赞 nielsen 11/8/2023 #1

OP 代码中最重要的问题是 和 被调用为 as 参数,然后用作函数内部的数组大小。但是,计算的是输入的数字量,而不是数组的大小。printAsortcountcountnumbers

该数组保存按数字顺序输入的所有唯一数字,因此无需排序,只需排除 0 条目(对应于范围内输入的数字)。numbers

最后,应检查 的返回代码,以验证是否实际收到了新号码。scanf()

总而言之,代码可以按如下方式调整:

#include <stdio.h>

void printA(int *numbers, int size) {
    for (int i = 0; i < size; i++) {
        if(numbers[i]) printf("%d ", numbers[i]);
    }
    printf("\n");
}

int main() {
    int numbers[101] = {0}; // using an array to keep track of numbers between 100 and 200
    int input, count = 0;

    printf("Enter numbers between 100 and 200 (enter a number outside this range to   finish):\n");

    while (1) {
        if(scanf("%d", &input) != 1)
        {
            printf("Invalid input\n");
            scanf("%*[^\n]%*c");  // Remove invalid input from buffer
            continue;
        }
        if (input < 100 || input > 200) {
            break;
        }
        if (numbers[input - 100] == 0) {
            count++;
            numbers[input - 100] = input;
        }
    }

    printf("\nTotal unique numbers entered: %d\n", count);

    printA(numbers, sizeof(numbers)/sizeof(numbers[0]));

    return 0;
}
0赞 greg spears 11/9/2023 #2

为了很好地说明原始代码的痛点,我创建了代码的修改版本:

请注意,代码是您的代码。它只是在几个小方面略有修改: 1.) 定义为 100;可重复使用且易于识别。 2.) 我们通过发送到打印例程来打印整个数组。这将说明所有空(零)阵列插槽。 3.) 用于模拟用户输入 -- 这是一个非常方便的测试约定。SIZE_ARRAYSIZE_ARRAYGetRandom(100, 200)

请注意打印前后的情况。数组自始至终都充斥着零:数组数据是不连续的。 此外,由于 (20) 被发送到 ,因此只能对前 20 个数组索引进行排序。如果在链接处运行代码,则会看到一些索引已排序,但只有前 20 个索引。countsort()

现在,请看这段代码 -- 它是相同的代码,但有一个小的改动:被赋予了,所以现在可以对整个数组进行排序。可以肯定的是,请注意,第二次打印的数据排序得很好。SIZE_ARRAYsort()sort()

以下只是众多可能解决方案中的又一个。它调整了数字的存储方式:它们现在是连续存储的(没有间隙),并且 - 当给定变量时 - 将能够对所有数据进行排序。缓冲区溢出保护也被添加到循环中 via 变量:sort()countmain()count

#include <stdio.h>

void sort(int *numbers, int count) 
{
int m, j;

   for (m = 0; m < count; m++) {
        for (j = 0; j < count - m - 1; j++) {
            if (numbers[j] > numbers[j + 1]) {
               int temp = numbers[j];
                numbers[j] = numbers[j + 1];
                numbers[j + 1] = temp;
            }
        }
    }
}

void printA(int *numbers, int count) 
{
    int i;
    for (i = 0; i < count; i++) {
        printf("%d ", numbers[i]);
    }
    printf("\n");
}


int main() 
{
    int numbers[101] = {0}; // using an array to keep track of numbers between 100 and 200
    int input, count = 0;
    printf("Enter numbers from 100 to 200 inclusive (enter a number outside this range to finish):\n");

    while (count < 101) /* Updated -- protect from array over-run */ 
    {
        scanf("%d", &input);
        if (input < 100 || input > 200) {
            break;
        }
        /* Updated -- numbers are not pre-sorted during storage.
        * Now the sort function can reach all the data entries.*/
        numbers[count++] = input;
    }
    printf("\nTotal unique numbers entered: %d\n", count);

    sort(numbers, count);
    printA(numbers, count);

    return 0;
}