我制作了一个名为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++相关问答推荐

strftime函数中%s的历史意义是什么?为什么没有记录?

如何将FileFilter添加到FileDialog GTK 4

常数函数指针优化

GCC预处理宏和#杂注GCC展开

警告:C++中数组下标的类型为‘char’[-Wchar-subpts]

是否所有C编译器在将浮点数转换为整型数时都会隐式删除小数?

如何知道我是否从非阻塞套接字读取所有内容

用C宏替换strncMP函数中的参数

如何使用C for Linux和Windows的标准输入与gdb/mi进行通信?

整型文字后缀在左移中的用途

将 struct 传递给函数

无法访问共享目标文件内的共享指针

从不兼容的指针类型返回&&警告,但我看不出原因

生成一个半RNG,结果用C表示(无随机/随机)

如何编写postgresql支持函数

Leet代码运行时错误:代码不会在Leet代码上编译,而是在其他编译器中编译,如netbeans和在线编译器

在C中,为什么这个带有递增整数的main函数从不因溢出而崩溃?

STM32:代码的执行似乎取决于它在闪存中的位置

macos/arm64 上地址空间不使用第一位吗?

如何在C中以0x格式打印十六进制值