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

时间:2018-02-08 23:48:28

标签: c file-io

我正在尝试读取一个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

任何人都可以帮我吗?

1 个答案:

答案 0 :(得分:0)

您的代码很奇怪,使用您发布的代码,您不应该写任何内容 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

请注意fscanf来电只会告诉您下一个字,而不是整行, 这是因为%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;
}

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);
}