【问题标题】:How to do conditional parsing with fscanf?如何使用 fscanf 进行条件解析?
【发布时间】:2010-08-18 16:18:01
【问题描述】:

我想从文本文件中解析一些行。有些行以x 开头并以几个y:z 继续,而另一些则完全由几个y:zs 组成,其中x,y,z 是数字。我尝试了以下代码,但它不起作用。第一行还读取了y 中的y:z

...
if (fscanf(stream,"%d ",&x))
if else (fscanf(stream,"%d:%g",&y,&z))
...

有没有办法告诉 scanf 只读取后面有空格的字符?

【问题讨论】:

    标签: c parsing scanf


    【解决方案1】:

    *scanf 系列函数不允许您在本地执行此操作。当然,您可以通过读取您知道每个输入行将出现的最小元素数量来解决该问题,验证*scanf 的返回值,然后逐步进行,一次一项,每次检查返回成功/失败的价值。

    if (1 == fscanf(stream, "%d", &x) && (x == 'desired_value)) {
        /* we need to read in some more : separated numbers */
        while (2 == fscanf(stream, "%d:%d", &y, &z)) { /* loop till we fail */
              printf("read: %d %d\n", y, z); 
        } /* note we do not handle the case where only one of y and z is present */
    } 
    

    最好的办法是使用fgets 读取一行,然后使用sscanf 自己解析该行。

    if (NULL != fgets(stream, line, MAX_BUF_LEN)) { /* read line */
       int nitems = tokenize(buf, tokens); /* parse */
    }
    
    ...
    size_t tokenize(const char *buf, char **tokens) {
        size_t idx = 0;
          while (buf[ idx ] != '\0') {
              /* parse an int */
              ...
          }
    }
    

    【讨论】:

      【解决方案2】:
      char line[MAXLEN];
      
      while( fgets(line,MAXLEN,stream) )
      {
        char *endptr;
        strtol(line,&endptr,10);
        if( *endptr==':' )
          printf("only y:z <%s>",line);
        else
          printf("beginning x <%s>",line);
      }
      

      【讨论】:

        【解决方案3】:

        我找到了一种粗略的方法,不需要切换到 fgets(从长远来看,这可能会更安全)。

        if (fscanf(stream,"%d ",&x)){...}
        else if (fscanf(stream,"%d:%g",&y,&z)){...}
        else if (fscanf(stream,":%g",&z)){
            y=x;
            x=0;
        }
        

        【讨论】:

          猜你喜欢
          • 2023-04-01
          • 1970-01-01
          • 2019-09-02
          • 1970-01-01
          • 2021-06-21
          • 1970-01-01
          • 1970-01-01
          • 2011-07-09
          • 1970-01-01
          相关资源
          最近更新 更多