使用结构从文件 I/O 读取然后打印的问题

2024-04-23

我正在尝试读取一个 CSV 文件并打印出该文件中的选择值,所有这些值都是字符串(末尾有一个字符),但我在实际打印它时遇到了麻烦。它应该忽略输入中的特定数据,例如ASO,ORL,PR,当然也可以跳过空白处。我不知道是文件 I/O 的问题还是我打印错误。有人可以帮忙吗?

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




typedef struct airdata{
    char *siteNum;
    char *LocalID;
    char *portName;
    char *city;
    char *state;
    char *lat;
    char *lon;
    char Tower;
} airdata;

int main(){
    FILE * fin = fopen("florida.csv", "rw");

    if((fin = fopen("florida.csv", "r")) == NULL){
        printf("etl ERROR: File inputFile not found.\n");
        return(0);
    }
    printf("\nFile opened successfully\n\n");
        printf("%-12s %-11s %-42s %-34s %-3s %-15s %-16s Tower\n",
                "FAA Site", "Short Name", "Airport Name", "City", "ST",
                "Latitude", "Longitude");

        printf("%-12s %-11s %-42s %-34s %-3s %-15s %-16s =====\n",
                "========", "==========", "============", "====", "==",
                "========", "=========");

            char buffer[1000];
            while(fscanf(fin, "%s", buffer) != EOF){
                    airdata * entry = malloc(sizeof(airdata));
                    fprintf(fin, "%s%s%s%s%s%*s%*s%*s%s%s%*s%*s%c%*s%*s", entry->siteNum, entry->LocalID,
                            entry->portName, entry->city, entry->state, entry->lat, entry->lon, entry->Tower);
                    printf("%s%s%s%s%s%*s%*s%*s%s%s%*s%*s%c%*s%*s", entry->siteNum, entry->LocalID,
                        entry->portName, entry->city, entry->state, entry->lat, entry->lon, entry->Tower);
        }

        fclose(fin);
}

这是输入和输出

IN:
03010.1*A,63FD,LINK FIELD,ALACHUA,FL,ASO,ORL,PR,29-41-53.0000N,082-29-29.0000W,PR,,NON-NPIAS,,N,,,2,0

OUT: 
03010.1*A    63FD        LINK FIELD                                 ALACHUA                            FL  29-41-53.0000N  082-29-29.0000W  N

谁能帮我这个?


你的代码很奇怪,用你发布的代码你不应该能够写任何东西fin,因为您打开它仅供阅读。

FILE * fin = fopen("florida.csv", "rw");

if((fin = fopen("florida.csv", "r")) == NULL)
...

您打开它一次以进行读/写,然后使用相同的方法再次重新打开它FILE*变量,读/写句柄丢失。这fprintf(fin, ...)来电应该 返回-1。

第二个问题是:

while(fscanf(fin, "%s", buffer) != EOF){
    airdata * entry = malloc(sizeof(airdata));
    fprintf(fin, "%s%s%s%s%s%*s%*s%*s%s%s%*s%*s%c%*s%*s", entry->siteNum, entry->LocalID,
            entry->portName, entry->city, entry->state, entry->lat, entry->lon, entry->Tower);
    printf("%s%s%s%s%s%*s%*s%*s%s%s%*s%*s%c%*s%*s", entry->siteNum, entry->LocalID,
        entry->portName, entry->city, entry->state, entry->lat, entry->lon, entry->Tower);
}

您为一个分配内存airdata每个循环中都有对象,但它始终是 未初始化,所以当你打印它的成员时你会得到垃圾。还fin仅供阅读打开, 写操作将会失败。你也没有释放内存,所以你是 在每次循环迭代时都会泄漏内存。最后你不检查是否malloc回报NULL.

请注意,fscanfcall 只会给你下一个单词,而不是整行, 就是这样因为%s匹配一系列非空白字符。

您在问题中向我们展示的输出对于您的代码是不可能的。

无论如何,您应该以不同的方式进行解析。阅读整行 和fgets然后使用strtok获取值:

int main(void)
{
    airdata **entries = NULL, **tmp;
    size_t num_of_entries = 0;
    char buffer[1024];
    const char *delim = ",\r\n";

    while(fgets(buffer, sizeof buffer, fin))
    {
        tmp = realloc(entries, sizeof *entries);
        if(tmp == NULL)
        {
            // one possible error handling
            fclose(fin);
            free_airdata_array(entries, num_of_entries);
            return 1;
        }

        entries = tmp;

        airdata *data = calloc(1, sizeof *data);

        if(data == NULL)
        {
            fclose(fin);
            free_airdata_array(entries, num_of_entries);
            return 1;
        }

        // parsing
        char **params[] = {
            &data->siteNum,
            &data->LocalID,
            &data->portName,
            &data->city,
            &data->state,
            &data->lat,
            &data->lon,
        };

        char *input = buffer, *token;

        for(size_t i = 0; i < sizeof params / sizeof *params; ++i)
        {
            token = strtok(input, delim);
            if(token == NULL)
            {
                flcose(fin);
                free_airdata_array(entries, num_of_entries);
                free_airdata(data);
                return 1;
            }

            *params[i] = strdup(token);

            if(*params[i] == NULL)
            {
                flcose(fin);
                free_airdata_array(entries, num_of_entries);
                free_airdata(data);
                return 1;
            }

            input = NULL; // subsequent calls of strtok expect NULL
        }

        token = strtok(NULL, delim);
        if(token == NULL)
            data->Tower = 0;
        else
            data->Tower = *token;

        entries[num_of_entries++] = data;
    }

    fclose(fin);
    do_something_with_the(entries, num_of_entries);

    free_airdata_arra(entries);

    return 0;
}

And the free功能:

void free_airdata_array(airdata **array, size_t num_of_entries)
{
    if(array == NULL)
        return;

    for(size_t i = 0; i < num_of_entries; ++i)
        free_airdata(array[i]);

    free(array);
}

void free_airdata(airdata *data)
{
    if(data == NULL)
        return;

    char **params[] = {
        &data->siteNum,
        &data->LocalID,
        &data->portName,
        &data->city,
        &data->state,
        &data->lat,
        &data->lon,
    };

    for(size_t i = 0; i < sizeof params / sizeof *params; ++i)
        free(*params[i]);

    free(data);
}

如果您的系统没有strdup:

char *strdup(const char *text)
{
    if(text == NULL)
        return NULL;

    char *ret = malloc(strlen(text) + 1);
    if(ret == NULL)
        return NULL;

    return strcpy(ret, text);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用结构从文件 I/O 读取然后打印的问题 的相关文章

随机推荐