【问题标题】:How to store words from file line with separators into a struct如何将带有分隔符的文件行中的单词存储到结构中
【发布时间】:2021-07-11 13:33:55
【问题描述】:

我有一个名为 cstats.txt 的输入文件,它只有一行:

name:age:phone:city

我有一个 struct Citizen:

typedef struct {             
    char name[100];          
    int age;               
    char city[100]
    char phone[10];   
} Citizen;  

我需要从文件中读取并将属性保存在结构中:

我试过了:


Citizen a;
fread(a, sizeof(Citizen), 1, "cstats.txt");

但我认为它没有保存属性。

我在 SO 上搜索了这里,但我发现的只是逐行阅读。

谢谢!

【问题讨论】:

  • 逐行读取,然后解析行。 [或者:一次读取一个字符,然后将它们组合起来]
  • fread的最后一个参数应该是指向文件的指针。
  • mprove,一个常见的被忽略的考虑是如果输入格式不正确该怎么办。您希望如何报告该错误?另外,这 4 个字段中的任何一个都可以为空吗?

标签: c file io


【解决方案1】:

fread 不是这项工作的最佳(最简单)工具,请改用fgets

阅读整行,然后使用sscanf 之类的内容解析字段,例如:

char line[250];

Citizen a;

FILE *file = fopen("cstats.txt", "r");

if (file != NULL)
{
    if (fgets(line, sizeof line, file))
    {
        sscanf(line, "%99[^:]:%d:%9[^:]:%99[^\n]", a.name, &a.age, a.phone, a.city);
    }
}

关于fread,它的一个很好的用例是从fwrite 写入的文件中读取数据,这将保证数据将被适当地格式化以直接读取到类似的缓冲区中用来写,例如:

Citizen a;
Citizen b;

FILE *file = fopen("file.txt", "w+"); // open to read and write

fwrite(&a, sizeof a, 1, file); // write Citizen a to file
fseek(file, 0, SEEK_SET);      // reset file position indicator
// rewind(file);               // alternative
fread(&b, sizeof b, 1, file);  // read data directly to Citizen b

在上面的代码中,为了简单起见,我跳过了返回值检查,您应该在代码中进行。

Live demo

【讨论】:

  • 考虑检查scanf() 结果 - 宽度限制的良好改进。
  • 我们可以使用 sizeof(Cititzen) 代替 sizeof(line) 吗?对不起,它没有“:”的空间
  • @improve,你正在将数据读入linefgets的第二个参数应该是目标缓冲区的大小
  • @改进不! fgets 的第二个参数是最大读取多少字节。这需要是缓冲区的大小,而不是其他东西的大小:) - 请参阅cplusplus.com/reference/cstdio/fgets
  • @MortenJensen Minor:“fgets 的第二个参数是要读取的最大字节数”-> 关闭但关闭 1。不超过第二个参数 - 读取 1 个字符。然而是的,它应该是缓冲区的大小以容纳附加的空字符。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-12
  • 2017-06-09
  • 2015-02-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-15
相关资源
最近更新 更多