c - 如何从文件中读取一个数组,对其进行排序,并将其打印到另一个文件中?

标签 c arrays file sorting

我的本​​地机器上有一个名为“data.in”的文件,内容如下:

1
5
6
6
8
10
33
24
20
3

和源代码:

#include <stdio.h>

int main (void)
{
    int n,i,a,V[i],ch,aux;
    FILE *f1, *f2;

    f1 = fopen("data.in", "r");
    f2 = fopen("data.out", "w"); //create data.out

    char line[1024];
    n = 0;
    while( fgets(line,sizeof(line),f1) != NULL)
       n++; // n = number of lines from the file

    for (i=0; i<n; i++)
        fscanf(f1,"%d", &V[i]); //reading the array from data.in

    do {
        ch=0;
        for (i=0; i<n-1; i++)
            if (V[i]>V[i+1])
            {
                aux=V[i]; V[i]=V[i+1]; V[i+1]=aux; ch=1;
            }
    } while (ch); //Bubble sort

    for (i=0; i<n; i++)
        fprintf(f2, "%d\n", V[i]); // print the array into data.out

    fclose(f1);
    fclose(f2);

}

编译很顺利,但每当我执行它时,data.out 只包含:

0
0
0
0
0
0
0
0
0
0

我什至尝试只打印数组,但它仍然是一堆零。 我什至尝试修改 data.in 以将所有数字放在同一行,但输出仍然只是一堆零。我一定是错过了什么......

我有点卡在这里,所以任何帮助将不胜感激。

最佳答案

如果您使用动态内存分配,您既不需要定义固定大小的数组并冒着需要比分配的空间更多的空间的风险,也不需要重新读取文件。 (另一方面,对于几十个甚至几千个数字的文件,这可能有点矫枉过正。)

您还可以使用标准库排序函数 qsort(),而不是使用冒泡排序。诚然,对于您处理的数据量,qsort() 和冒泡排序之间的差异不太可能轻易衡量,但如果您从数十个数字移动到数千个数字, O(N2) 和 O(N log N) 算法之间的区别变得明显。 (请参阅 How to sort an array of structures in C?,了解为什么按原样编写下面的 intcmp()。)

此外,您应该对输入操作(和内存分配)进行错误检查。使用代码中显示的 err_exit() 函数这样的简单函数可以使错误报告简洁明了,因此不那么繁琐,也减少了省略错误检查的借口。我在我的大部分程序中使用了 err_exit() 的一个更有特色的变体,但那是在它自己的源文件中的代码,它有自己的头文件。许多程序(包括下面的重写)不检查输出操作是否成功;他们可能应该。

这会导致类似这样的代码:

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

static int intcmp(const void *p1, const void *p2);
static void err_exit(const char *fmt, ...);

int main(void)
{
    static const char n1[] = "data.in";
    static const char n2[] = "data.out";
    FILE *f1 = fopen(n1, "r");
    FILE *f2 = fopen(n2, "w");
    int *V = 0;
    char line[1024];
    int n = 0;
    int max_n = 0;

    if (f1 == 0)
        err_exit("Failed to open file %s for reading\n", n1);
    if (f2 == 0)
        err_exit("Failed to open file %s for writing\n", n2);

    while (fgets(line, sizeof(line), f1) != NULL)
    {
        int v;
        if (sscanf(line, "%d", &v) != 1)
            break;
        if (n == max_n)
        {
            int new_n = (max_n + 2) * 2;
            int *new_V = realloc(V, new_n * sizeof(*V));
            if (new_V == 0)
                err_exit("Failed to realloc array of size %d\n", new_n);
            V = new_V;
            max_n = new_n;
        }
        V[n++] = v;
    }

    qsort(V, n, sizeof(V[0]), intcmp);

    for (int i = 0; i < n; i++)
        fprintf(f2, "%d\n", V[i]);

    free(V);
    fclose(f1);
    fclose(f2);
    return(0);
}

static int intcmp(const void *p1, const void *p2)
{
    int i1 = *(int *)p1;
    int i2 = *(int *)p2;
    if (i1 < i2)
        return -1;
    else if (i1 > i2)
        return +1;
    else
        return 0;
}

static void err_exit(const char *fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    vfprintf(stderr, fmt, args);
    va_end(args);
    exit(1);
}

关于c - 如何从文件中读取一个数组,对其进行排序,并将其打印到另一个文件中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17770827/

相关文章:

python - 在python中写入输出文件

c - 我只看到主机的 "world hello"而不是设备

c - 链表,如果头部不存在如何插入?

c - 为什么这个 union 中的结构似乎向后排序

java - 如何在 cs50 第一题中获取用户的输入?

来自 JSON 数组的 mySQL WHERE IN

javascript - d3.js - 强制布局和节点位置

c - 用中文写的文件(我想?)

file - 使用 AppleScript 立即删除文件

c - 为什么溢出数组初始化会发出警告而溢出赋值却不会?