【问题标题】:Confusion about sscanf关于 sscanf 的困惑
【发布时间】:2011-03-11 19:24:10
【问题描述】:

我想从我从文件中取出的一行中读取浮点数(以及之后的整数)。当我调试它时,我可以看到它从文件中取出行没问题,但是当我尝试扫描它时,我得到了垃圾。这是我的代码:

    while(fgets(line, 1000, file) != EOF)
    {
        //Get the first character of the line
        c = line[0];

        if(c == 'v')
        {
            sscanf(line, "%f", &v1);
            printf("%f", v1);
        }
    }

v1 中存储的值是垃圾。为什么这不起作用,我怎样才能从这条线上得到浮点数和整数?

【问题讨论】:

    标签: c scanf


    【解决方案1】:

    您在对 sscanf 的调用中包含了第一个字符(即“v”),因此调用失败,v1 保持不变(其中包含垃圾)。试试这个:

    sscanf(line+1, "%f", &v1);
    

    【讨论】:

    • 而且,v1 是垃圾,因为它未初始化。检查 sscanf 是否真的初始化了你给它的参数,if(sscanf(line+1, "%f", &v1)) != 1) { //error }
    【解决方案2】:

    大概 v1 是一个浮点数?

    在这种情况下,在内存中打印一个浮点数就好像它是一个 'c' 字符串会很糟糕..
    你可能想试试printf("%f",v1);

        if(c == 'v')
        {
            sscanf(line, "%f", &v1);
    

    如果行以 'v' 开头,那么您将其发送给 scanf 并要求它将其转换为浮点数?您可能想要移动一个字符(或者如果您有其他填充,则可以移动更多),然后开始读取第 [1] 行的浮点数?

    【讨论】:

    • 哈哈,谢谢。但无论如何,那只是为了调试。我真正的问题是 v1 包含垃圾。知道如何解决这个问题吗?
    • 在实际代码中,如果你有它,你应该使用 strtod() - 如果字符串不是有效的浮点数,它可以标记。查看代码,您需要跳过行首的“v”并将 line[1] 发送到 sscanf()
    【解决方案3】:

    您的 printf 语句应如下所示:

    printf("%f\n", v1);
    

    另外,您应该检查 sscanf 的返回值,以检查它是否甚至找到并存储浮点数:

    if(sscanf(line, "%f", &v1) < 1){
        /* didn't read float */
    }else{
        printf("%f\n", v1);
    }
    

    【讨论】:

      【解决方案4】:

      由于您在执行sscanf() 调用时知道line 中的第一个字符是字母'v',因此您也可以说sscanf() 无法成功将其转换为@ 987654324@ 或 float 因为 'v' 不是以字符串形式呈现的任何有效浮点数的一部分。

      你应该检查sscanf()的返回值;它会显示 0(没有成功的转换),从而告诉您出了点问题。

      你可能会成功:

      if (sscanf(line+1, "%f", &v1) != 1)
          ...error...
      

      【讨论】:

      • 感谢您的回复,您的解释很清楚。如果我做了类似 sscanf(line, "%s%f", v1) 之类的事情,那会很好吗?
      • @Jeff:如所写,不 - sscanf() 会尝试将字符串复制到浮点数,这将是可怕的。可能有用的是sscanf(line, "%*s%f", &amp;v1);,其中最重要的* 表示“进行转换但不要将其分配到任何地方”。请注意,%*s 会跳过一系列非空白字符。如果输入字符串是v 3.1416('v' 后面的空格),那么这可以正常工作;如果输入是v3.1416v+3.1416(无空格),则该数字将作为字符串的一部分使用。
      • @Jeff - 这会因为几个原因而崩溃。首先,您传递的是v1 而不是&amp;v1。其次,您指定了两种格式转换,但只提供了一个放置它们的位置。你可以使用sscanf(line, "v%f", &amp;v1)
      • 我在发布(并对其进行测试)后立即意识到它只会将其放入字符串中。 * 似乎相当有用,并且可以在这种情况下使用,因为 v 后面有空格,但我认为 line+1 会是更好的解决方案。 @Ted Hopp:是的,这实际上可能比使用 %*s%f
      猜你喜欢
      • 2019-05-17
      • 2020-03-06
      • 2016-03-16
      • 2013-07-27
      • 1970-01-01
      • 2012-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多