【问题标题】:Sorting structure variables(3 ints) in file from smallest to largest C从最小到最大C对文件中的结构变量(3个整数)进行排序
【发布时间】:2021-12-08 05:03:02
【问题描述】:

我需要为我的项目排序我的 2 个文本文件。其中一个文本文件采用学生 ID、课程 ID 和分数格式,另一个采用学生 ID 格式。我用fprintf写了他们两个的值,所以我在阅读时使用fscanf,但是我的函数不能正常工作,你能告诉我我的错误在哪里吗?

(我删除了不起作用的旧代码,因为我继续使用不同的代码)

编辑:我尝试根据下面的解决方案创建一个代码sn-p,但是当我进入while循环时,fscanf开始得到错误的数字。你能找出我的错误在哪里吗?

编辑:在这里编辑后,我做了 fopen 检查。他们没有问题。 while 循环运行一次后关闭,我认为,在 if fscanf 部分中,fscanf 没有正确读取数字,因此它以 break 退出循环。

最有可能损坏的部分:

    FILE *index = fopen("index.txt", "r");
    FILE *record = fopen("record.txt", "r");
    if (!index)
        return;
    if (!record)
        return;
    int array[n][3];
    //int *array = (int *)malloc(n *3 sizeof(int));???
    int count = 0;
    int i=0,temp,id,course,score;
    while (1)
    {  
        if(count==n) break;
        if (fscanf(record, "%d", &id) != 1) break;
        if (fscanf(record, "%d", &course) != 1) break;
        if (fscanf(record, "%d", &score) != 1) break;
        array[count][0] = id;
        array[count][1] = course;
        array[count][2] = score;
        count++;
    }

如果错误在别处,其余功能供您浏览:

void sort_for_bin_search(int n)
{
    FILE *index = fopen("index.txt", "r");
    FILE *record = fopen("record.txt", "r");
    if (!index)
        return;
    if (!record)
        return;
    int array[n][3];
    //int *array = (int *)malloc(n *3 sizeof(int));???
    int count = 0;
    int i=0,temp,id,course,score;
    while (1)
    {  
        if(count==n) break;
        if (fscanf(record, "%d", &id) != 1) break;
        if (fscanf(record, "%d", &course) != 1) break;
        if (fscanf(record, "%d", &score) != 1) break;
        array[count][0] = id;
        array[count][1] = course;
        array[count][2] = score;
        count++;
    }
     for (i = 1; i < n - 1; i++)
    {
        for (int j = 0; j < n - 1; j++)
        {
            if(array[i][0] > array [j][0])
            {
            temp=array[j][0];
            array[j][0] = array[i][0];
            array[i][0] = temp;

            temp=array[j][1];
            array[j][1] = array[i][1];
            array[i][1] = temp;

            temp=array[j][2];
            array[j][2] = array[i][2];
            array[i][2] = temp;
            }
            else if((array[i][0]==array[j][0])&&(array[i][1]>array[j][1]))
            {
            temp=array[j][0];
            array[j][0] = array[i][0];
            array[i][0] = temp;

            temp=array[j][1];
            array[j][1] = array[i][1];
            array[i][1] = temp;

            temp=array[j][2];
            array[j][2] = array[i][2];
            array[i][2] = temp;
            }

        }
    }
    fclose(record);
    fclose(index);
    FILE *index2 = fopen("index.txt", "w");
    FILE *record2 = fopen("record.txt", "w");
    for (i = 0; i < n; i++)
    {
        fprintf(index2,"%d\n",array[i][0]);
        fprintf(record2,"%d %d %d\n",array[i][0],array[i][1],array[i][2]);
        //printf("%d %d %d\n",array[i][0],array[i][1],array[i][2]);
    }
    //free(array);
    fclose(record2);
    fclose(index2);
}

【问题讨论】:

  • 你绝对需要检查fopen是否失败
  • 欢迎来到 SO。 “工作不正常”是什么意思?请提供您的输入、输出和预期输出。如果您收到任何错误消息,它们是什么?
  • 您的方法是错误的,您对 fseek 的使用对文本文件没有意义。您还应该分别处理从文件中读取、排序和写入文件,而不是同时进行这三项操作
  • fseek(record, 3*sizeof(int) * j, SEEK_SET); 您计算的是字节大小,而不是文本表示。正如 Jabberwocky 所写,fseek 和文本文件不能很好地结合在一起。
  • 我是文件操作的新手,如果我不能这样使用,您建议我改用什么?

标签: c function file sorting


【解决方案1】:

看起来您正在执行冒泡排序,并且在每次迭代中您都从磁盘读取/写入。磁盘操作非常缓慢。如果您读取一次数组,它会更容易和更快。然后对该单个数组进行排序。

例子:

void sort_for_bin_search(int n)
{
    //assumes that `n` is the number of lines in this file
    if (n < 1) return;
    FILE* fin = fopen("index.txt", "r");
    if (!fin)
        return;
    FILE* fout = fopen("record.txt", "w");
    if (!fout)
        return;

    int* arr = malloc(n * sizeof(int));
    if (!arr) return;
    int count = 0;
    while (1)
    {
        if (count == n)
            break;
        int id, course, score;
        if (fscanf(fin, "%d", &id) != 1) break;
        if (fscanf(fin, "%d", &course) != 1) break;
        if (fscanf(fin, "%d", &score) != 1) break;
        arr[count] = id;
        count++;
    }
    //add code for sorting arr
    for (int i = 0; i < count; i++)
        fprintf(fout, "%d\n", arr[i]);

    free(arr);
    fclose(fin);
    fclose(fout);
}

然后你可以排序,例如使用冒泡排序。

使用printf将每一步的数据打印到屏幕上,这将有助于调试。

void sort_for_bin_search(int n)
{
    FILE* fin = fopen("input_file.txt", "r");
    if (!fin)
    {
        printf("input error\n");
        return;
    }
    int array[n][3];
    int count = 0;
    while (1)
    {
        int id, course, score;
        if (count == n) break;
        if (fscanf(fin, "%d", &id) != 1) break;
        if (fscanf(fin, "%d", &course) != 1) break;
        if (fscanf(fin, "%d", &score) != 1) break;
        array[count][0] = id;
        array[count][1] = course;
        array[count][2] = score;
        count++;
    }
    n = count;
    printf("reading:\n");
    for (int i = 0; i < n; i++)
        printf("%d %d %d\n", array[i][0], array[i][1], array[i][2]);

    printf("\nsort\n");
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n - 1 - i; j++)
        {
            if (array[j][0] > array[j + 1][0])
            {
                int temp;
                temp = array[j][0];
                array[j][0] = array[j + 1][0];
                array[j + 1][0] = temp;

                temp = array[j][1];
                array[j][1] = array[j + 1][1];
                array[j + 1][1] = temp;

                temp = array[j][2];
                array[j][2] = array[j + 1][2];
                array[j + 1][2] = temp;
            }
        }
    }
    fclose(fin);

    printf("sorted\n");
    for(int i = 0; i < n; i++)
        printf("%d %d %d\n", array[i][0], array[i][1], array[i][2]);

    printf("write to file\n");
    FILE* fout = fopen("output_file.txt", "w");
    if(!fout)
    {
        printf("output error\n");
        return;
    }
    for (int i = 0; i < n; i++)
        fprintf(fout, "%d %d %d\n", array[i][0], array[i][1], array[i][2]);
    fclose(fout);
}

【讨论】:

  • 由于他们还没有教我们递归,他们特别想使用冒泡排序或二进制排序,所以我选择了冒泡排序,因为它更容易。
  • 谢谢@chux-ReinstateMonica
  • @Yodax93 忽略qsort,我只是把它放在那里快速测试代码。您应该能够重写您的代码以对数组 arr 进行冒泡排序。
  • 我稍微更改了代码并将其集成到我的项目中,但在 while 循环内代码开始中断,结果数组开始返回非常奇怪的数字。你能找出错误在哪里吗?
  • 我不知道哪个是您的输入文件,哪个是输出文件。我重命名了文件。使用正确的名称,并在每一步在屏幕上打印数组。你的冒泡排序似乎也有问题,我用我的版本替换了它。在移动到 3-D 数组之前,您应该真正从 1-D 数组开始。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-16
  • 1970-01-01
  • 2017-08-01
  • 1970-01-01
  • 2021-12-10
  • 1970-01-01
相关资源
最近更新 更多