分类程序C

时间:2018-09-07 20:55:21

标签: c arrays sorting

我正在编写代码以对int的txt文件进行排序,然后在用户要求某个索引处的数字时显示它们,但是每次运行代码时,我都会遇到分段错误。 我该怎么做才能解决此问题?

void insert_sorted(long *sorted, int count, long value)
{
    int i = 0;

    sorted[1024] = value;
    if (count == 0) return;
    for (i = count; i >= 0; i--) {
        if (value < sorted[i - 1])
            sorted[i] = sorted[i - 1];
        else break;
    }
    sorted[i] = value;
}
int main(int argc, char *argv[])
{
    FILE *infile = NULL;
    int count = 0;
    long sorted[1024];
    long value;
    int i = 0;
    if (argc < 2) {
        fprintf(stderr, "Usage : %s <file_name>/n", argv[0]);
        return 1;
    }
    infile = fopen(argv[1], "r");
    if (NULL == infile) {
        perror("fopen");
        return -1;
    }
    /* while file not ends */
    while (!feof(infile)) {
        fscanf(infile, "%ld\n", &value); /* fetch value */
        insert_sorted(sorted, count, value); /* sort */
        ++count; /* increase number of sorted values */
    }
    /* display values */
    printf("Enter Index : ");
    int index;
    scanf("%d", &index);
    if (index == -1)
        fclose(infile);
    printf("%d ", sorted[index]);

    /* cleanup */
    if (infile) {
        fclose(infile);
        infile = NULL;
    }
    return 0;
}

4 个答案:

答案 0 :(得分:2)

sorted [1024] = value;中的操作;会使您的程序崩溃。排序数组的大小仅为1024,因此最大索引为1023。

一种解决方法是在main()函数中将sorted的大小更改为1025。

for循环中的另一项操作可能会使程序崩溃:当i = 0时,对已排序的[i-1]的访问将捕获异常。

答案 1 :(得分:2)

数组sorted的大小为1024:

    long sorted[1024];

这表示数组sorted的有效索引范围是01023

insert_sorted()函数中,您尝试访问超出其范围的sorted数组:

    sorted[1024] = value;
           ^^^^

访问数组元素超出其大小是未定义的行为,其中包括程序可能会导致分段错误。

实际上,insert_sorted()函数中存在逻辑错误。由于进行了sorted值检查,因此它永远不会将第一个值存储在count数组中的适当位置:

    if (count == 0) return;

第一次count的值将为0,并且函数返回而未将value存储在sorted数组中的适当位置。另外,您应该检查count值,如果该值大于数组大小,则函数应给出适当的错误消息。您可以这样做:

#define ARR_SZ 1024

void insert_sorted(long *sorted, int count, long value) {
    int i = 0;

    if (count > ARR_SZ) {
        fprintf (stderr, "Array is exhausted");
        //may you want to change the return type of function from void to 
        //int and return a value in case of error.
        //Based on the return value, the caller of this function can take
        //appropriate action.
        return;
    }

    for (i = count; i > 0; i--) {
        if (value < sorted[i - 1])
            sorted[i] = sorted[i - 1];
        else 
            break;
    }
    sorted[i] = value;
}

int main(int argc, char *argv[])
{
    FILE *infile = NULL;
    int count = 0;
    long sorted[ARR_SZ];
    ......
    ......
    ......
}

当您从用户那里获取index输入时,请确保添加一个检查,确认它是否小于0或大于或等于count。如果是这样,则不应访问sorted[index]

    scanf("%d", &index);

    if ((index >= count) || (index < 0)) {
         //print error message and do not access sorted[index]
    }

您不需要这个:

    if (index == -1)
        fclose(infile);

因此,当用户输入-1时,fcloseinfile调用两次。确保一旦关闭打开文件的FILE *,就不要再对其调用fclose

答案 2 :(得分:1)

当您尝试使用大于其维的键来写入元素数组时,出现分段错误。 在这种情况下,您正在写

sorted[1024] = value

具有最大的键1023(长排序的[1024]表示从0到1023)。

您应该更改

long sorted[1024];

使用

long sorted[1025];

否则您应该更改

sorted[1024] = value;

使用

sorted[1023] = value;

我没有阅读您的代码来告诉您哪个更好。

答案 3 :(得分:0)

  

该如何解决?

您可以在调试器中运行程序。

您可以单步执行代码,一次执行一条指令,在执行过程中检查变量的值,也可以让程序在调试器的监视下运行。如果程序导致段故障,调试器将在确切的故障点将其中断,从而使您可以查看引起故障的代码。如果对代码为什么会这样做有疑问,它甚至可以让您查看所涉及变量的值。