c - 从文件中检索丢失的条目

标签 c arrays nested-loops

假设有一个文本文件“measurements”,如下所示:

         London     1   0.5
         London     2   1.0
          Tokyo     3   2.0
         London     6  18.4
          Tokyo    11  -1.0
          Tokyo     1  -0.3
        Toronto     3  -1.0
         London     8   8.0
        Toronto    11  11.0
        Toronto    12  10.4
         London     7  -5.6

第一列存储城市名称,第二列表示测量发生的月份,第三列只是给定城市该月的平均气温。现在,我想要的是读取所有这些数据,并找出某个城市没有条目的月份(例如伦敦 3、东京 6 等),并将所有这些数据放入名为“错误”的文本文件中。 这是我尝试过但最终陷入困境的方法:

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

struct City {
    char name[20];
    int month;
    float avg;

};

int scan(struct City *arr, int len)
{
    FILE *fp = fopen("measurements.txt", "r");
    if (fp == NULL) {
        printf("Error while reading.");
        exit(1);
    }
    int i = 0;
    while ((fscanf(fp,"%12s%d%f\n", arr[i].name, &arr[i].month, &arr[i].avg)) == 3)
        i++;
    fclose(fp);
    return i;
}

void sort(struct City *arr, int len)
{
    struct City temp[100];
    int         i, j;

    for (i = 0 ; i < len - 1 ; i++) {
        for (j = i + 1 ; j < len; j++) {
            int compare = strcmp(arr[i].name, arr[j].name);
            if (compare > 0) {
                temp[i] = arr[i];
                arr[i]  = arr[j];
                arr[j]  = temp[i];
            }
        }
    }

}

int main()
{
    struct City array[100];
    int len = scan(array,1000);
    sort(array, len);

    FILE *fout;

    fout = fopen("missing.txt","w");
    if (fout == NULL) {
        printf("Error while printing");
        exit(1);
    }

    int i;
    for (i = 1 ; i < len ; i++) {
        int j, m = 1, found = 0;
        for (j = 1 ; j <= 12 ; j++) {
            while (strcmp(array[m - 1].name, array[m].name) == 0) {
                if (array[m - 1].month == j)
                    found=1;
            }
            if (found == 0)
                fprintf(fout,"%15s %d",array[i].name, j);
        }
    }
    fclose(fout);
    return 0;
}

但是,当我运行该程序时,文件“输出”仍然为空,我猜这是由于代码末尾附近的嵌套循环中的错误所致。我觉得必须有一种更简单、更优雅的方法来做到这一点。您将如何解决这个问题?

最佳答案

您可以构建一个月份数组,其中包含一个整数值,指示月份是否存在,然后对于每个花旗名称,进行迭代,直到城市名称在 while 循环中发生变化,使数组中的每个条目等于 1 对于文件中的每个条目,在数组将包含缺失月份位置 - 1 和 0 后,如果确实如此,则输出文件的值。

这是代码

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

struct City {
    char name[20];
    int month;
    float avg;

};

int scan(struct City *arr, int len)
{
    FILE *fp = fopen("measurements.txt", "r");
    int   i  = 0;

    if (fp == NULL) {
        printf("Error while reading.");
        exit(1);
    }

    while ((fscanf(fp,"%12s%d%f\n", arr[i].name, &arr[i].month, &arr[i].avg)) == 3)
        i++;
    fclose(fp);

    return i;

}

void sort(struct City *arr, int len)
{
    struct City temp[100];
    int         i, j;

    for (i = 0 ; i < len - 1 ; i++) {
        for (j = i + 1 ; j < len; j++) {
            int compare = strcmp(arr[i].name, arr[j].name);
            if(compare > 0) {
                temp[i] = arr[i];
                arr[i]  = arr[j];
                arr[j]  = temp[i];
            }
        }
    }

}

int main()
{
    struct City array[100];
    FILE       *fout;
    int         len;
    const char *previous;
    int         month;

    len = scan(array, 100);
    if (len == 0)
        return -1;
    sort(array, len);

    fout = fopen("missing.txt","w");
    if (fout == NULL) {
        printf("Error while printing");
        return -1;
    }
    previous = NULL;
    month    = 1;
    for (int i = 0 ; i < len ; i++) {
        int months[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

        previous = array[i].name;
        while (strcmp(previous, array[i].name) == 0)
        {
            int month;
            month = array[i].month;
            if ((month >= 0) && (month < 12))
                months[month - 1] = 1;
            i += 1;
        }
        i -= 1;

        for (int j = 0 ; j < 12 ; j++)
        {
            if (months[j] != 0)
                continue;
            fprintf(fout, "%15s%5d\n", previous, j + 1);
        }
    }
    fclose(fout);

    return 0;
}

关于c - 从文件中检索丢失的条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28584448/

相关文章:

bash - 遍历 bash 中的值对

c - 从 C 可执行文件增加 ext4 文件系统上 linux 文件大小而不在文件中创建漏洞的最快方法是什么?

C - 将代码分解成单独的文件

php - MySql PHP 选择 JSON 值

c++ - 为什么二维数组在不应该打印的地方打印 1?

javascript - 您可以使用 Array.flatMap 在 Javascript 中返回 n 个选择 k 个组合吗?

PHP 同时中断和继续

将包含 12 位数字的 16 位数组转换为 8 位连续数组

c - C语言浮点除法

android - 如何防止我的程序排队按钮按下