c - C语言读取文件

标签 c parsing file-io tokenize strtok

我有一个输入文件,需要从中提取单词。单词只能包含字母和数字,因此任何其他内容都将被视为分隔符。我尝试了 fscanf、fgets+sscanf 和 strtok,但似乎没有任何效果。

while(!feof(file))
{
    fscanf(file,"%s",string);
    printf("%s\n",string);
}

上面一个显然不起作用,因为它不使用任何定界符所以我用这个替换了这一行:

 fscanf(file,"%[A-z]",string);

它可以很好地读取第一个单词,但文件指针不断倒带,因此它一遍又一遍地读取第一个单词。

所以我使用 fgets 读取第一行并使用 sscanf:

sscanf(line,"%[A-z]%n,word,len);
line+=len;

这个也不起作用,因为无论我尝试什么,我都无法将指针移动到正确的位置。我试过 strtok 但找不到如何设置定界符

while(p != NULL) {
printf("%s\n", p);
p = strtok(NULL, " ");

这个显然以空白字符作为分隔符,但我实际上有 100 个分隔符。

我是否遗漏了一些东西,因为从文件中提取单词一开始似乎是一个简单的概念,但我尝试过的却没有任何效果?

最佳答案

考虑构建一个最小的 lexer 。当处于 word 状态时,只要它看到字母和数字,它就会一直保留在其中。当遇到别的东西时,它会切换到状态 delimiter 。然后它可以在状态 delimiter 中做完全相反的事情。

下面是一个可能有用的简单状态机示例。为了简洁起见,它仅适用于数字。 echo "2341,452(42 555"| ./main 将在单独的行中打印每个数字。它不是词法分析器,但在状态之间切换的想法非常相似。

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

int main() {
  static const int WORD = 1, DELIM = 2, BUFLEN = 1024;
  int state = WORD, ptr = 0;
  char buffer[BUFLEN], *digits = "1234567890";
  while ((c = getchar()) != EOF) {
    if (strchr(digits, c)) {
      if (WORD == state) {
        buffer[ptr++] = c;
      } else {
        buffer[0] = c;
        ptr = 1;
      }
      state = WORD;
    } else {
      if (WORD == state) {
        buffer[ptr] = '\0';
        printf("%s\n", buffer);
      }
      state = DELIM;
    }
  }
  return 0;
}

如果状态数量增加,您可以考虑用 switch block 替换检查当前状态的 if 语句。可以通过将 getchar 替换为将整个输入 block 读取到临时缓冲区并遍历它来提高性能。

如果必须处理更复杂的输入文件格式,您可以使用词法分析器生成器,例如 flex。他们可以为您完成定义状态转换和词法分析器生成的其他部分的工作。

关于c - C语言读取文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8526595/

相关文章:

scala - 如何在 Scala 中高效地同时处理 300 多个文件

c++ - 关闭 fstream 是否保证文件系统同步?

c++ - 原始数据包创建导致 IP 字段顺序不正确

c - 数组作为函数的参数

php - 如何使用 Symfony2 对数据进行后台解析?

c# - 在 C# 中解析 JSON API

c - C 中的 TrueType 字体解析

python - python 在 mac 上打开文件到哪里?

c++ - 是否有可能有 'times out' 的源代码(在某个时刻后变得无效)?

c - 将 void* 类型转换为 long