【问题标题】:Reading data from a file and into a struct从文件中读取数据并写入结构
【发布时间】:2014-02-15 19:09:35
【问题描述】:

我正在尝试从文件中读取数据并将数据存储在结构中。结构如下所示:

struct someData {
    int number;
    char *name;
};

文件中的数据可以是任何格式。现在我正在尝试以 CSV 格式阅读。数据将始终是一个字符串,后跟一个整数。

some string data,100
another string,500

这是我试图读取数据并将其放入结构中的代码部分。

FILE *ifp;
char *mode = "r";
char *name;
int number;

ifp = fopen("myDataFile.txt", mode);

if (ifp == NULL) {
    fprintf(stderr, "Can't open input file in.list!\n");
    exit(1);
}

// read up to 100 characters up to a comma, then a decimal
while(fscanf(ifp, "%100[^,],%d\n", name, &number) != EOF){ 

    // print out the data we got 
    printf("Data from file:  %s  %d", name, number);


    struct someData *newData = (struct someData *) malloc(sizeof(struct someData));
    newData->number = number;
    newData->name = name;
    printf("Name: %s  Number: %d\n\n",newData->name, newData->number);
    } 

打印语句给了我以下内容

Data from file: some string d 100
Name: some string d  Number: 100

Data from file: another stri  Number: 500
Name: another stri  Number 500

第二个名字被截断,实际上最终打印了几个奇怪的字符。我认为我的 fscanf 在 while 循环中有问题。我尝试了其他一些方法来获取数据,例如使用 %s 而不是 %100 但没有任何效果。

【问题讨论】:

  • char *name; 名称不指向数组。在if中的 fscanf 之前

标签: c


【解决方案1】:

您需要将 char *name; 更改为char name[101];(不是struct 中的那个)。

如果你改了会更好:

    while(fscanf(ifp, "%100[^,],%d\n", name, &number) != EOF){

    while(fscanf(ifp, " %100[^,],%d", name, &number) == 2){

这个:

  • 添加初始空白的跳过
  • 删除尾随 \n,这有时会导致问题
  • 验证是否已读取两个有效参数。

newData->name = name; 也不起作用:您需要类似 newData->name = strdup(name); 的东西。

另外,作为风格问题,我建议改变:

     struct someData *newData = (struct someData *) malloc(sizeof(struct someData));

到:

     struct someData *newData = malloc(sizeof *newData);

这将避免一些冗余,即“DRY”。

你永远不会保存newData;我想您打算将其添加到链表或其他类似容器中。

此外,您最终需要添加错误检查,但这超出了本问题的范围。

【讨论】:

  • 做到了!谢谢!
  • 感谢 strdup() 的提示,这是我的下一个问题。是的,在这之后它会进入一棵树。
  • @JDD:只是为了澄清一点。 fscanf 中的尾随 \n 并不意味着“吃掉换行符”。这意味着“吃掉所有(零个或多个)空白字符,直到遇到非空白字符或文件结尾”(%[...] 中的规则不同) .所以你所拥有的没有错,但我的建议一般来说更安全。但是我的解决方案仍然存在name尾随 空格的潜在问题,这可能不是您想要的,并且可能会导致问题。您必须手动删除这些,或使用例如Trim。此外,您可能想使用%100[^,\n]
【解决方案2】:

您正在使用未初始化的指针节点。函数 fscanf 需要为字符串提供一些缓冲区,而您没有提供任何缓冲区。

【讨论】:

    猜你喜欢
    • 2015-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-28
    • 2023-03-14
    • 2019-08-11
    • 1970-01-01
    相关资源
    最近更新 更多