C:将数据值读入结构

时间:2017-12-29 14:18:33

标签: c file pointers struct

我有一个csv文件,其中的信息部分用","分隔。我想要做的是获取这些信息并将其存储在不同的结构变量中,但我不知道如何制作它以便将信息存储在那里。

这是我的主要文件:

struct items beer [100];

int main(int argc, char **argv) {
    char *oneline, *tok;
    char envara[512];
    char delim [] = ",";
    FILE *fp;
    int i = 0;
    fp = fopen("varor.csv", "r");

    printf("ID\n");

    while (!feof(fp)) {
        if (fp == NULL) {
            fprintf(stderr, "File varor.csv could not be opened\n");
            exit(-1);
        }
        fgets(envara, 512, fp);
        envara[strlen(envara) -1] = '\0'; 

        printf("En rad; %s\n", envara);

        oneline = strdup(envara);
        tok = strtok(oneline, delim);

        while (tok != NULL) {
            printf("%s\n", tok);
            tok = strtok(NULL,delim);
        }
    }
    return 0;
}

这是我的结构:

struct items {
    int itemnumber;
    char name [100];
    float price;
    float volyme;
    char types [100];
    char style [100];
    char package [20];
    char country [20];
    char producer [50];
    float alcohol_amount;
};

1 个答案:

答案 0 :(得分:3)

应使用fgets逐行读取文件。如果您读取的流位于文件结尾,它将返回空指针。使用feofwrong

尽管将读取行标记为有时候更好的方法,但您也可以使用sscanf将每行的数据提取到struct items。为了使我的示例更易于阅读,我已将struct items更改为:

typedef struct item_t {
    char name[20];
    float weight;
    unsigned long id;
    float price;
} Item;

如果您的CSV文件中没有标题行,则可以将其解析为:

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

#define MAX_ITEM 5

typedef struct item_t {
    char name[20];
    float weight;
    unsigned long id;
    float price;
} Item;

int main() {
    Item items[MAX_ITEM];
    int i = 0, parsedData;

    char line[512];
    FILE* csvFile = fopen("test.csv", "r");

    if(csvFile == NULL) {
        perror("Failed to open file.");
        exit(EXIT_FAILURE);
    }

    while(fgets(line, sizeof(line), csvFile) != NULL && i < MAX_ITEM) {
        parsedData = sscanf(line, "%20[^,],%f,%lu,%f",
                items[i].name, &items[i].weight, &items[i].id, &items[i].price);
        if(parsedData == 4)
            items[i++].name[19] = '\0';
        else
            fprintf(stderr, "Format error in line: %s\n", line);
    }

    fclose(csvFile);
    return 0;
}

在我的示例中,第一个值也可以包含空格,格式字符串的%20[^,]部分表示:读取任何不是逗号字符的内容,最多20个字符。

Live Demo

注意:使用sscanf函数不安全,它可能在很多方面导致溢出和未定义的行为。因此,您有责任通过格式字符串保持CSV文件的字段可解析,并保持sscanf函数的参数列表正确。我的示例将跳过当前行,如果它在第一个逗号之前包含超过20个字符,但是例如如果为id指定的数字太长,则无法阻止整数溢出。要编写更安全的代码,请考虑使用适当的输入检查为每个不同的字段编写自己的转换函数,然后使用例如使用这些函数对行进行标记化以填充struct items