【问题标题】:easy way to parse a text file?解析文本文件的简单方法?
【发布时间】:2011-03-06 14:23:29
【问题描述】:

我正在制作一个负载均衡器(一个非常简单的)。它查看用户空闲了多长时间,以及系统上的负载以确定进程是否可以运行,并以循环方式遍历进程。

控制流程所需的所有数据都存储在一个文本文件中。 该文件可能如下所示:

 PID=4390 IDLE=0.000000 BUSY=2.000000 USER=2.000000
 PID=4397 IDLE=3.000000 BUSY=1.500000 USER=4.000000
 PID=4405 IDLE=0.000000 BUSY=2.000000 USER=2.000000
 PID=4412 IDLE=0.000000 BUSY=2.000000 USER=2.000000
 PID=4420 IDLE=3.000000 BUSY=1.500000 USER=4.000000

这是一个大学作业,但是解析文本文件不应该是其中的重要部分,这意味着我可以使用任何对我来说最快的方式来实现。

此文件中的条目将在流程完成或在控制下添加时添加和删除。

关于如何解析这个的任何想法?

谢谢。

【问题讨论】:

  • 解析很容易。最困难的部分是确保你在其他人正在编写它时不要尝试阅读它。

标签: c string parsing text


【解决方案1】:

这里有一段代码可以解析你的文件,同时也解释了你的文件可能不可用(即fopen 可能失败),或者在你阅读它时被写入(即fscanf可能会失败)。请注意,您可能不想使用无限循环(这比要复制粘贴到您的项目中的实际代码更像伪代码,我没有尝试运行它)。另请注意,考虑到那里的睡眠持续时间,它可能会很慢:您可能想要使用更高级的方法,这更像是一种 hack。

int pid;
float idle, busy, user;

FILE* fid;
fpos_t pos;
int pos_init = 0;

while (1)
{
  // try to open the file
  if ((fid = fopen("myfile.txt","rw+")) == NULL)
  {
     sleep(1); // sleep for a little while, and try again
     continue; 
  }

  // reset position in file (if initialized)
  if (pos_init)
     fsetpos (pFile,&pos);

  // read as many line as you can
  while (!feof(fid))
  {
     if (fscanf(fid,"PID=%d IDLE=%f BUSY=%f USER=%f",&pid, &idle, &busy, &user))
     {
        // found a line that does match this pattern: try again later, the file might be currently written
        break;
     }

     // add here your code processing data         

     fgetpos (pFile,&pos); // remember current position
     pos_init = 1; // position has been initialized
  }

  fclose(fid);
}

【讨论】:

  • 你忘记了所有的和号,所有的字段(减去pid)都是floats。
  • 我不知道该给谁正确答案。我选择 Greg 是因为您将循环和文件打开作为更完整的答案。
  • @Blackinary:我大量修改了我的答案,以说明您正在阅读的文件可能不可用,或者在您阅读时可能正在被写入。
  • 实际上,它不可能不可用,因为在程序的早期,如果它不可用,我会创建它。而且它不能被写入,因为我已经将它封闭在羊群中。我错过了什么吗?
  • 啊。我认为该文件是由一系列其他进程编写的,并且您的程序正在同时读取它。所以没关系 :P 如果你的文件完全在你的(单线程)程序的控制之下,那么你不需要锁定它(如果你的设计是正确的)。
【解决方案2】:

就解析而言,类似这样的循环:

int pid;
float idle, busy, user;
if(fscanf(inputStream, "PID=%d IDLE=%f BUSY=%f USER=%f", %pid, &idle, &busy, &user)!=4)
{
    /* handle the error */
}

但正如@Blrfl 指出的那样,最大的问题是避免在您的应用程序正在读取文件而其他人正在写入文件时发生混淆。要解决这个问题,你应该使用锁或类似的东西;参见例如flock 系统调用。

【讨论】:

    【解决方案3】:

    在循环中使用fscanf。这是关于使用 fscanf 的 GNU C 教程。

    /* fscanf example */
    #include <stdio.h>
    
    typedef struct lbCfgData {
        int pid;
        double idle;
        double busy;
        double user;
    } lbCfgData_t ;
    
    int main ()
    {
        // PID=4390 IDLE=0.000000 BUSY=2.000000 USER=2.000000
        lbCfgData_t cfgData[128];
    
        FILE *f;
    
        f = fopen ("myfile.txt","rw+");
        for (   int i = 0; 
                i != 128 // Make sure we don't overflow the array
                && fscanf(f, "PID=%u IDLE=%f BUSY=%f USER=%f", &cfgData[i].pid, 
                    &cfgData[i].idle, &cfgData[i].busy, cfgData[i].user ) != EOF; 
                i++
            );
    
        fclose (f);
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-27
      • 2020-06-07
      • 1970-01-01
      • 1970-01-01
      • 2014-03-05
      • 2019-04-07
      • 2017-12-31
      • 1970-01-01
      相关资源
      最近更新 更多