【问题标题】:How do I make a token parser in C?如何在 C 中制作令牌解析器?
【发布时间】:2023-03-23 06:43:01
【问题描述】:

我已经看到各种控制台应用程序的“配置”文件(是的,文本文件),如下所示

<token> <value>

我将如何在 C 中解析这样的东西,其中 可以是字符串、字母甚至是整数/浮点数/双精度数?

我读到了这个问题“How do I parse a token from a string in C?”,主要推荐使用 strtok,但它不是线程安全的,我计划生成多个线程(前提是我能够完成我的应用程序)

附言 这是一个令牌和值的示例

user username123
pass 123456

啊,我忘记了棘手的部分。我还必须能够解析一个令牌,它有多个值,或者用逗号分隔。

【问题讨论】:

  • 在您链接到的线程上,有一条评论说“您可以使用线程安全的 strtok_r()。您可以在同一个手册页中看到它们。”
  • 定义什么是&lt;token&gt; 和&lt;value&gt;,提供具体答案很容易。
  • @Arak 我什至提供了一个例子。 [at]Vache,我一定是错过了,我会看看,同时我正在等待更多建议:)
  • 可能会调查 Lex 和 Yacc (en.wikipedia.org/wiki/Lex_(software))

标签: c parsing token


【解决方案1】:

使用regexp怎么样?如果您在 linux 中,您只需 #include &lt;regexp.h&gt; 即可使用它。和man regexp.h将了解如何使用它。按字符串存储它们。并且,如果它们是数字,请使用 sprintf 将它们转换为 unmber。

【讨论】:

    【解决方案2】:

    试试这个:

        FILE* fp;
        fp = fopen("in.txt","r");
    
        if(fp == NULL)
        {
            printf("Can't open/read file.\n");
            exit(1);
        }
    
        char* buf = NULL;
        char* key = malloc(64);
        char* val = malloc(64);
        size_t read;
        size_t len = 0;
    
        if(key == NULL || val == NULL)
        {
            printf("malloc failed.\n");
            exit(1);
        }
    
    
        while((read = getline(&buf, &len, fp)) != -1)
        {
            sscanf(buf,"%s %s", key, val);
            printf("<%s> <%s>\n", key, val);
        }
    
        if(buf != NULL)
        {
          free(buf);
        }
    
        free(key);
        free(val);
    
        fclose(fp);
    

    in.txt 文件:

    key value
    key1 value1
    

    C 应用程序输出:

    <key> <value>
    <key1> <value1>
    

    希望对你有所帮助。

    【讨论】:

      【解决方案3】:

      使用getc(),将输入流中的字符读入每行缓冲区。一旦你点击了一个标记分隔符,你strncpy() or strdup() 将每行缓冲区转换为一个标记char*。如果需要,在令牌内分隔符(例如逗号)上再次解析令牌,一次抓取一个字符并将其存储在每个令牌缓冲区中,直到您遇到令牌内分隔符。一旦你点击了一个行分隔符,将每行缓冲区复制到一个值char*。如果您知道该值为 int、float 等,请使用 C 函数将 char* 转换为这些原语(例如,strtol() 等)。如果您有多个令牌-值对,请保留一个数组或指向令牌和值 char* 变量的指针。重复直到 EOF(文件结束)。

      【讨论】:

      • 我会建议 strtol 而不是 atoi,因为您无法判断它是否失败或使用 atoi 的数字是否为 0。
      【解决方案4】:

      我认为fgets() 和sscanf() 是你的朋友:

      int parseTokens(FILE *filePtr, char **tokens, char **values)
      {
          int i = 0;
      
          char line[128];
      
          while (fgets(line, 127, filePtr)) {
              tokens[i] = malloc(64);
              values[i] = malloc(64);
      
              sscanf(line, "%s %s", tokens[i], values[i]);
      
              i++;
          }
      
          return i;
      }
      
      int main(void)
      {
          char *tokens[20];
          char *values[20];
      
          FILE *filePtr = fopen("~/test.txt", "r");
      
          if (!filePtr)
          {
              fprintf(stderr, "Error opening file: %s", strerror(errno));
          }
      
          int count = parseTokens(filePtr, tokens, values);
      
          for (int i = 0; i < count; i++) {
              printf("%s %s\n", tokens[i], values[i]);
      
              free(tokens[i]);
              free(values[i]);
          }
      
          fclose(filePtr);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-02-06
        • 2011-07-25
        • 1970-01-01
        • 1970-01-01
        • 2010-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多