从C中具有不同数据类型的文件中读取特定行

时间:2017-11-29 22:07:20

标签: c file scanf ansi-c

我的代码有一个可怕的问题。我通过以下方式保存一些数据:

void savetofile()
{
  fprintf(savefile, "%d\n", run); // here are 1 or 2 characters
  fprintf(savefile, "%d\n", gender); // 1 character
  fprintf(savefile, "%s\n", name); // here is string, max 20 characters
  fprintf(savefile, "%d\n", points1); // between 1 and 3 characters
  fprintf(savefile, "%d\n", points2); // between 1 and 3 characters
}

保存后如何阅读?我可以用某种方式具体说明:

fscanf(savefile, "%d", &gender);

阅读具体的第2行?

也许当我将数据保存到文件时:

void savetofile()
{
  fprintf(savefile, "%d ", run); // here are 1 or 2 characters
  fprintf(savefile, "%d ", gender); // 1 character
  fprintf(savefile, "%s ", name); // here is string, max 20 characters
  fprintf(savefile, "%d ", points1); // between 1 and 3 characters
  fprintf(savefile, "%d ", points2); // between 1 and 3 characters
}

阅读会更容易吗?

2 个答案:

答案 0 :(得分:1)

许多方法可以解决这个问题 - 每个方法都有优点和缺点。

带有“标签”的单行怎么样,文件中的标记表示数据ID?

void savetofile(int run, int gender, char *name, int points1, int points2) {
  fprintf(savefile, "r:%d g:%d n:\"%s\" p1:%d p2:%d\n", 
    run, gender, name, points1, points2);
}

// return 1: success, EOF:no more 0:problem data
int readfile(int &run, int &gender, char *name, int *points1, int *points2) {
  char buf[100];  // Size: 2x longest expected line
  if (fgets(buf, sizeof buf, savefile) == NULL) return EOF;
  if (sscanf(buf, "r:%2d g:%1d n:\"%19[^\"]\" p1:%3d p2:%3d", 
    &run, &gender, name, &points1, &points2) != 5) return 0;
  return 1;
}

各种其他改进可能,尤其是额外的错误检查,但上面是要实现一些想法。

答案 1 :(得分:0)

fscanf不知道也不关心,因为行尾标记(例如换行符)被视为某个空格字符。特别是,fscanf格式控制字符串中的空格,制表符,换行符扮演相同的角色(跳过类似空格的字符),并在作为输入发生时由fscanf同样处理。

如果您关心特定的行,则应逐行阅读输入文件。使用getline之类的here(或fgets)来读取行。换句话说,如果您关心线条,则需要进行顺序读取。

你可以解析你的文件两次,并记住(例如在一些动态分配的数组中)所有线的偏移在第一遍中开始(在第二遍中使用ftell和更晚fseek;直接访问只能访问某些字节offset,而不能访问某些行号。

读完某些内容后,您可以使用常见的parsing技术(特别是sscanf%n或您的recursive descent parser)来解析它。

请务必指定 文字file format 的语法,例如以EBNF表示法。新行的作用是您的选择(您可以将它们视为空格,通过在整个文件上使用lexing和解析技术,或者您可以通过读取每一行并解析该行来逐行处理。)

顺便说一句,你的用例宁愿提出其他一些方法。例如。使用数据库(可能是Sqlite),使用索引文件àgdbm,以某种文本格式对数据进行编码,例如JSON,XML或YAML(您可以使用它们)找到很多图书馆。)

请注意,大多数关于compilers的书籍(尤其是Dragon Book)都以各种解析技巧的解释开头。你应该阅读那部分内容。