【问题标题】:Reading line per line, and evaluating strings into coordinates using fgets() and sscanf()每行读取一行,并使用 fgets() 和 sscanf() 将字符串评估为坐标
【发布时间】:2015-12-22 00:48:39
【问题描述】:

我正在尝试使用 fgets 和 sscanf 读取多行不同长度的顶点。

(1,6),(2,6),(2,9),(1,9)
(1,5)

我的程序进入了一个无限循环,卡在第一个顶点内。

    char temp3[255];
    while(fgets(temp3, 255, fp)!= NULL){
        printf("Polygon %d: ", polycount);
        while(sscanf(temp3, "(%d,%d)", &polygonx[polycount][vertcount], &polygony[polycount][vertcount]) != EOF){
            sscanf(temp3, ",");
            printf("(%d,%d),",polygonx[polycount][vertcount], polygony[polycount][vertcount]);
            vertcount++;
        }
        vertcounts[polycount] = vertcount;
        vertcount = 0;
        polycount++;
    }

我必须能够将顶点的 x 和 y 值输入到多边形数组中,所以我坚持使用 sscanf。我也遇到了问题,因为我在互联网上找不到任何可以扫描每行不同数量元素的内容。

【问题讨论】:

  • sscanf 一遍又一遍地读取相同的内容,从而导致无限循环。它并没有像你想象的那样前进。
  • 早先修复了 sscanf 以及 @iharob 的建议。我的主要问题是我的指针在 fgets() 迭代后没有更新。不管怎么说,还是要谢谢你。 :)

标签: c file-io scanf point-in-polygon


【解决方案1】:

因为这个

while(sscanf(temp3, "(%d,%d)", 
  &polygonx[polycount][vertcount], &polygony[polycount][vertcount]) != EOF)
 {
 }

我认为永远不会是true,因为scanf() 返回成功扫描的参数数量,我会这样做

while(sscanf(temp3, "(%d,%d)", 
  &polygonx[polycount][vertcount], &polygony[polycount][vertcount]) == 2)
 {
 }

你的代码不起作用,因为它不满足sscanf()返回EOF的条件,以下来自最后引用的手册页

如果在第一次成功转换或匹配失败发生之前到达输入结尾,则返回值EOF。如果发生读取错误,也会返回EOF,在这种情况下会设置流的错误指示符(参见ferror(3)),并设置errno 来指示错误。

因此,如果在第一次成功转换之前输入或发生匹配失败,那么您似乎还没有到达结尾,这根据文件的内容是有意义的。第二部分当然只适用于文件流。

而不是 sscanf(temp3, ",") 不按照你的想法做,你可以这样做

next = strchr(temp3, ',');
if (next != NULL)
    temp3 = next + 1;
else
    /* you've reached the end here */

这是一个关于如何解析这个文件的建议

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

int
main(void)
{
    const char temp3[] = "(1,6),(2,6),(2,9),(1,9)\n(1,5)";
    char *source;
    int x, y;
    int count;
    source = temp3;
    while (sscanf(source, "(%d,%d)%*[^(]%n", &x, &y, &count) == 2)
    {
        /* this is just for code clarity */
        polygonx[polycount][vertcount] = x;
        polygony[polycount][vertcount] = y;
        /* Process here if needed, and then advance the pointer */
        source += count;
    }
    return 0;
}

"%n" 说明符捕获到目前为止扫描的字符数,因此您可以使用它将指针前进到源字符串中扫描的 las 位置。

"%*[^(" 将跳过所有字符,直到找到下一个 '('

有关"%n" 说明符和%[ 说明符的更多信息,请参阅sscanf(3)

【讨论】:

  • 谢谢,但我使用的是 char temp3[255],所以我认为这就是为什么你的解决方案仍然不适合我的原因。
  • @bhunter 你可以很容易地创建一个指向数组的指针,这在 c 语言中是很自然的事情,请我编辑一下。
  • 程序仍在无限循环中。我认为它不适用于 fgets()。
  • 请注意,我有未知数量的行和顶点,所以上面的建议,所有字符串都在 temp3,不是我的情况。
  • @bhunter 所以应该具体说明它到底是什么。
【解决方案2】:

如果成功读取sscanf,在这种情况下将返回2sscanf 返回填充的变量数。

检查它是否返回2,这将在此处指示成功。

while(sscanf(temp3,"(%d,%d)",&polygonx[polycount][vertcount],&polygony[polycount]][vertcount]) != EOF)

而不是这个,像这样检查 -

 while(sscanf(temp3,"(%d,%d)%*c",&polygonx[polycount][vertcount],&polygony[polycount]][vertcount])== 2)
                             ^ to exclude the comma after it             

还要忽略坐标后的',',你使用-

sscanf(temp3, ",");

不正确。在上面的sscanf 中,您可以使用%*c 说明符阅读并丢弃它。

【讨论】:

  • "%*c" 可以,如果在元组末尾只有一个, 或任何其他字符,"%*[^(]" 会更健壮。
  • 我认为%*c 在这里没有任何用处。如果sscanf 不存在,则其行为方式相同。
  • @iharob 我猜代码的格式是固定的。并且 ( 将在下一次迭代中匹配。所以我们不必担心这个。
  • @CoolGuy 不,你是对的。我确实做了一些愚蠢的事情。确实是大错特错。 :|
  • 您的答案中的解决方案不起作用。 sscanf 不阅读。一旦你的答案中的sscanf 返回 2,你就会得到一个无限循环。
猜你喜欢
  • 1970-01-01
  • 2021-11-09
  • 1970-01-01
  • 2016-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多