简体   繁体   English

如何使用fscanf进行条件解析?

[英]How to do conditional parsing with fscanf?

I have some lines I want to parse from a text file. 我有一些我想从文本文件中解析的行。 Some lines start with x and continue with several y:z and others are composed completely of several y:z s, where x,y,z are numbers. 有些行以x开头并继续使用几个y:z ,其他行完全由几个y:z s组成,其中x,y,z是数字。 I tried following code, but it does not work. 我尝试了下面的代码,但它不起作用。 The first line also reads in the y in y:z . 第一行也读入y中的y:z

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

Is there a way to tell scanf to only read a character if it is followed by a space? 有没有办法告诉scanf只读取一个字符后跟一个空格?

The *scanf family of functions do not allow you to do that natively. *scanf系列函数不允许您本机执行此操作。 Of course, you can workaround the problem by reading in the minimum number of elements that you know will be present per input line, validate the return value of *scanf and then proceed incrementally, one item at a time, each time checking the return value for success/failure. 当然,您可以通过读取每个输入行中存在的最小元素数来解决问题,验证*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 */
} 

Your best bet to handle this is to read in a line using fgets and then parse the line yourself using sscanf . 处理此问题的最佳方法是使用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 */
          ...
      }
}
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);
}

I found a crude way to do, what I wanted without having to switch to fgets (which would probably be safer on the long run). 我发现了一种粗暴的方法,我想要的是不需要切换到fgets(从长远来看可能更安全)。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM