我制作了一个名为qsort.txt的文本文件,并在文件中写入了任意多个整数(在我的例子中,准确地说是35个整数).我的目标是计算该文件中有多少个整数,将它们放入由malloc()定义的数组中,并使用qsort()对它们进行排序.之后,我希望将排序后的数字写入一个名为sorted.txt的文本文件中.

这是我的代码,但显然不像预期的那样工作.此外,我想更灵活的代码,所以在FILE *fa = fopen(argv[1], "r+")argv[1],这样我就可以把任何其他文本文件进行排序.无论如何,我的问题是我不知道如何计算文件中有多少个整数.

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

int compare(const void *a, const void *b) {
    if (*(int*)a < *(int*)b)
        return -1;
    else if (*(int*)a > *(int*)b)
        return 1;
    else
        return 0;
}

int main(int argc, char **argv) {

    FILE *fa = fopen(argv[1], "r+");
    if (!fa)
        exit(1);
    FILE *fb = fopen("sortirano.txt", "w+");

    long duljina, i;
    long *ptr, *zapis;
    long count = 0;

     while (!feof(fa))
         count++;

     printf("%lu\n", count);

     fseek(fa, 0, SEEK_END);
     duljina = ftell(fa);
     fseek(fa, 0, SEEK_SET);

     ptr = (long *)malloc(sizeof(long));

     while (!feof(fa)) {
         fscanf(fa, "%lu", ptr);
         count++;
     }
     printf("count: %lu\n", count);
     for (i = 0; i < count; i++)
         printf("%lu ", ptr[i]);

    printf("\n");

    free(ptr);

    fclose(fa);
    fclose(fb);

    return 0;
}

EDIT:

这是我的新代码,它更简单:

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

int compare(const void *a, const void *b) {
    if (*(long*)a > *(long*)b)
        return 1;
    if (*(long*)a < *(long*)b)
        return -1;
    else
        return 0;
}

int main() {
    FILE *fa = fopen("qsort.txt", "r"); assert(fa != NULL);
    FILE *fb = fopen("sorted.txt", "w+"); assert(fa != NULL);

    long *ptr;
    long save;
    long count = 0;
    long i;
    long k;

    while ((fscanf(fa, "%ld", &save)) == 1) //number of elements
        prebroji++;

    printf("count: %ld\n", count); //checking how many elements i have, just to make sure it works ok

    ptr = (long *)malloc(count * sizeof(long)); //mallociranje

    for (i = 0; i < count; i++)
        fscanf(fa, "%ld", &ptr[i]);

    for (i = 0; i < count; i++) //checking if numbers were saved at malloc array
        printf("%ld ", ptr[i]);

    qsort(ptr, count, sizeof(long), compare);

    for (i = 0; i < count; i++) //checking if sorted correctly
        printf("%ld ", ptr[i]);

    for (i = 0; i < count; i++)
        fprintf(fb, "%ld", ptr[i]);

    printf("\n");

    free(ptr);
    fclose(fa);
    fclose(fb);

    return 0;
}

但它不起作用:我得到的都是打印的零.

推荐答案

由于该文件只包含整数和空格,您可以使用fscanf("%ld", ...)解析它,并将数字存储到一个数组中,当您读取更多数字时,您可以重新分配该array.

请注意以下备注:

  • 您的比较功能可以与qsort一起使用.

  • 不需要打开模式串中具有+的文件以进行更新,

  • 也没有任何必要寻求文件的结尾.

  • while(!feof(fa))测试文件结尾总是错误的.相反,您应该测试fscanf()是否成功,并根据需要重新分配array.

以下是修改后的版本:

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

int compare(const void *aa, const void *bb) {
    const long int *a = aa;
    const long int *b = bb;
    return (*a > *b) - (*a < *b);
}

int main(int argc, char **argv) {
    if (argc < 2) {
        fprintf(stderr, "missing argument\n");
        return 1;
    }
    FILE *fa = fopen(argv[1], "r");
    if (!fa) {
        fprintf(stderr, "cannot open %s: %s\n", argv[1], strerror(errno));
        return 1;
    }

    long *ptr = NULL;
    size_t alloc = 0, count = 0;
    long value;

    while (fscanf(fa, "%ld", &value) == 1) {
        if (count == alloc) {
            size_t new_alloc = alloc + alloc / 2 + 32;
            long *new_ptr = realloc(ptr, sizeof(*ptr) * new_alloc);
            if (!new_ptr) {
                fprintf(stderr, "out of memory for %zu entries\n", new_alloc);
                free(ptr);
                fclose(fa);
                return 1;
            }
            ptr = new_ptr;
            alloc = new_alloc;
        }
        ptr[count++] = value;
    }
    fclose(fa);

    printf("count: %zu\n", count);

    qsort(ptr, count, sizeof(*ptr), compare);

    const char *outfile = "sorted.txt";
    FILE *fb = fopen(outfile, "w");
    if (!fb) {
        fprintf(stderr, "cannot open %s: %s\n", outfile, strerror(errno));
        free(ptr);
        return 1;
    }

    for (size_t i = 0; i < count; i++) {
        fprintf(fb, "%ld\n", ptr[i]);
    }

    fclose(fb);
    free(ptr);

    return 0;
}

EDIT:

您的新代码有多个问题:

  • 在更新模式下不需要打开sorted.txt,只需使用"w".

  • 你应该在打开第二个文件后assert(fb)

  • prebroji应该是count

  • 您应该在分配数组后添加assert(ptr)

  • 分配数组后必须加rewind(fa);才能从头开始重新读取文件.这解释了为什么您获得的所有值都是0,因为您不测试每次try 都返回0EOF的返回值fscanf().

  • 如果更改数组的类型,写入qsort(ptr, count, sizeof(*ptr), compare);以避免大小不一致就不那么脆弱了.

  • 同样,写ptr = malloc(count * sizeof(*ptr))更可靠,因为如果你改变ptr的类型,它仍然是一致的.

  • 应在fprintf(fb, "%ld", ptr[i])中添加分隔符,以分隔写入输出文件的数字.

C++相关问答推荐

减法运算结果的平方的最快方法?

Win32API Wizzard97 PropSheet_SetWizButton不工作

为什么我会收到释放后堆使用错误?

Vcpkg的配置文件

是否可以通过调用两个函数来初始化2D数组?示例:ARRAY[STARTING_ROWS()][STARTING_COLUMNS()]

为什么双精度d=flt_max+flt_max;在c语言中得到inf的结果

如何将另一个数组添加到集合中,特别是字符串?

获取前2个连续1比特的索引的有效方法

将数组插入数组

如何将C中的两个字符串与从文件接收的字符串中的字符数进行比较

GCC错误,共享内存未定义引用?

从CentOS 7到Raspberry PI 2B的交叉编译-无法让LIBC和System Include标头一起工作

STM32 FATFS用户手册(Um1721)中的代码正确吗?

当我在34mb的.mp4文件中使用FREAD时,我得到了一个分段错误,我如何解决它?

无算术运算符和循环的二进制乘法

Makefile无法将代码刷新到ATmega328p

WSASocket在哪里定义?

为什么使用 C 引用这个 char 数组会导致 Stack smasing?

我该如何处理这个 C 90 代码中的内存泄漏?

CS50多项,印刷优胜者