【问题标题】:Reading different data from a textfile delimited with semicolons in C从C中用分号分隔的文本文件中读取不同的数据
【发布时间】:2009-12-01 09:34:09
【问题描述】:

如何将用分号分隔的不同数据记录读入 C 中的数组中?

来自文本文件: 文本一; 12.25;正文二; 5个;正文三; 1.253

fopen ...
for(i = 0; i < nrRecords; i++) {
fscanf(myFile, " %[^;];", myRecords[i].firstText);  /* Ok first text*/
fscanf(myFile, "%lf", &myRecords[i].myDouble1);     /* But goes wrong with first double */
fscanf(myFile, " %[^;];", myRecords[i].secondText); 
fscanf(myFile, "%d", &myRecords[i].myInt1);     
fscanf(myFile, " %[^;];", myRecords[i].thirdText); 
fscanf(myFile, "%lf",&myRecords[i].myDouble2);    
}
fclose...

【问题讨论】:

  • 如果您将每个字段读取为字符串 %[^;];,您是否得到正确的文本(例如第二个字段中的“12.25”)?
  • 不,问题是我正在将它读入具有“固定”类型的结构数组中。
  • 我试过了,它工作正常。你能显示 myRecord 结构的定义吗?
  • struct myRecord{ char text1[20];双倍价格;字符文本2[30];诠释天然橡胶;字符文本3[30];双倍价格2; };
  • 它是如何“出错”的?为什么不检查 fscanf 的返回值?

标签: c text file input


【解决方案1】:

通常的建议是阅读整行,然后使用 sscanf 或 strtok 或其他任何方式对其进行解析。如果您直接从文件中 sscanf,那么很容易丢失您在输入文件中的位置。 (即第一次出现不匹配的情况,你需要一种方法跳过它,除非你想在那里中止。)

【讨论】:

  • 失去自己的位置有多容易?跳过该行的其余部分并不难,如果您在错误中折腾当前行,那么您要做的就是这样做:void ignoreline(FILE* f) { char c; for (;;) switch (fgetc(f)) { case '\n': case EOF: return; default:; }
【解决方案2】:

我会使用fgets 从文件中读取一行,strtok 用分号分隔,strcpy 复制字符串,strtod 转换为 double 和 strtol 转换为 long (然后向下转换为整数)。

或者,阅读该行并使用状态机来遍历每个字符并执行正确的操作。例如,您要将每个字符复制到 firstText 直到到达分号,然后使用strtod 吃掉双精度,跳过分号,将字节复制到 secondText,等等。

或者,使用单个 scanf 格式字符串将行分解为所有字段

fscanf(myFile, " %[^;];%lf;%[^;];%d;%[^;];%lf", 
    myRecords[i].firstText,
    &myRecords[i].myDouble1,
    myRecords[i].secondText,
    &myRecords[i].myInt1,
    myRecords[i].thirdText,
    &myRecords[i].myDouble2);

并且,正如其他人所说,检查fscanf的返回值。

我更喜欢一次读一行,以避免一条错误的行搞砸随后的所有转换。

【讨论】:

    【解决方案3】:

    一种方法是使用strtok。然后将结果类型转换为 int 或 float。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-06
      • 2014-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-21
      相关资源
      最近更新 更多